![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
����Ū���ٱ�ɾ���������줿����Ȥ��Ƥ� Haskell ��ͭ̾�Ǥ����� Scheme ����ʬŪ���ٱ�ɾ����������Ƥ��ޤ���
> (define laz (delay (+ 1 2))) > laz #<promise:laz> > (promise? laz) #t > (force laz) 3 > (* 10 (force laz)) 30���������դ������Τϥץ��ߥ��� force �ˤ�äƾ��줺���ץ��ߥ��Τޤޤ��Ȥ������ȤǤ��� �Ĥޤꡢforce �ϥץ��ߥ������ͤ�����ޤ������ץ��ߥ��������Ѥϵڤܤ��ޤ��� ���äƥץ��ߥ��ϲ��٤Ǥ�Ȥ��ޤ魯���Ȥ��Ǥ��ޤ���
̵�¥ꥹ�Ȥϡ�
(<val> . <promise>) (1)���ͤˡ�car �������ꤷ���ͤǡ�cdr �����ץ��ߥ�����ʤäƤ��륳�����ɽ���ޤ��� cdr ���Υץ��ߥ��� force ����Ȥޤ���(1) �Τ褦�ʥ����뤬��������褦������ҹ�¤�� ��뤳�Ȥˤ�ä�̵�¥ꥹ�Ȥ�ɽ���ޤ��ʿޣ��ˡ������������Ҥˤ��ɽ���ϡ��̾�Υꥹ�Ȥ�Ʊ���Ǥ����� cdr ����ץ��ߥ��ˤ��뤳�Ȥˤ�ä��̾�Υꥹ�ȤȤϰۤʤꡢ̵�¥ꥹ�Ȥ�ɽ���Ǥ���褦�ˤʤ�ޤ���
[code 1]
01: ;;;;; basic functions and a macro 02: 03: ;;; car for lazy evaluation 04: (define lazy-car car) 05: 06: ;;; cdr for lazy evaluation 07: (define (lazy-cdr ls) 08: (force (cdr ls))) 09: 10: ;;; lazy cons 11: (define-syntax lazy-cons 12: (syntax-rules () 13: ((_ a b) (cons a (delay b))))) 14: 15: ;;; lazy map 16: (define (lazy-map fn . lss) 17: (if (memq '() lss) 18: '() 19: (lazy-cons (apply fn (map lazy-car lss)) 20: (apply lazy-map fn (map lazy-cdr lss))))) 21: 22: ;;; lazy filter 23: (define (lazy-filter pred ls) 24: (if (null? ls) 25: '() 26: (let ((obj (lazy-car ls))) 27: (if (pred obj) 28: (lazy-cons obj (lazy-filter pred (lazy-cdr ls))) 29: (lazy-filter pred (lazy-cdr ls)))))) 30: 31: ;;; returns n-th item of the lazy list 32: (define (lazy-ref ls n) 33: (if (= n 0) 34: (lazy-car ls) 35: (lazy-ref (lazy-cdr ls) (- n 1)))) 36: 37: ;;; returns first n items of the ls 38: (define (head ls n) 39: (if (= n 0) 40: '() 41: (cons (lazy-car ls) (head (lazy-cdr ls) (- n 1)))))
(inf-seq a0 f) �ϺƵ�Ū������ˤʤäƤ��ꡢ ����������顢��ब a0 �裲�ब (f a0) �Ǥ��ꡢ �� n+1 ��� (f an) ��ɽ����뤳�Ȥ��ʷ��ɽ������Ƥ��ޤ��� inf-seq ��Ȥ�������������������Ϥ��줾�� (ari a0 d), (geo a0 r) ���ͤ� ����Ǥ��ޤ��������ǡ�a0, d, r �Ϥ��줾�� ��ࡢ�����������ɽ���ޤ���
[code 2]
01: ;;;; sequences 02: 03: ;;; infinite sequences represented by a_(n+1) = f(a_n) 04: (define (inf-seq a0 f) 05: (lazy-cons a0 (inf-seq (f a0) f))) 06: 07: ;;;arithmetic sequence 08: (define (ari a0 d) 09: (inf-seq a0 (lambda (x) (+ x d)))) 10: 11: ;;; geometric sequence 12: (define (geo a0 r) 13: (inf-seq a0 (lambda (x) (* x r))))inf-seq ��̵�¿��Ǥ��뤳�Ȥ��ǧ���Ƥߤޤ��礦��sample 2�ˡ� geo ��Ȥäƽ�� 1������ 2 ��������� g1 �� ��� 1������ 1/2 ��������� g2 ���ꡢhead ��Ȥäƺǽ�� 10 ���ɽ�������ޤ��������ȿ��Ǥ��Ƥ��뤳�Ȥ���ǧ����ޤ���
���ˡ���������� lazy-filter �ˤĤ���Ĵ�٤Ƥߤޤ��礦�� �ޤ���(ari 1 1) �ǡ� (1 2 3 ....) �Ȥ������� ar1 �� ���ޤ���head �ǡ��ǽ�� 10 ���ɽ��������� 1 ���� 10 �ޤǤ�ɽ������ޤ����� ����ˡ�lazy-filter ��Ȥäƶ�������Ф����ǽ�� 10 ���ɽ��������� 2 ���� 20 �ޤǤ�ɽ������ޤ���
[sample 2]
> (define g1 (geo 1 2)) ;��� 1 ���� 2 ��������� > (define g2 (geo 1 (/ 1 2))) ;��� 1 ���� 1/2 ��������� > (head g1 10) (1 2 4 8 16 32 64 128 256 512) > (head g2 10) (1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512) > (head (lazy-map * g1 g2) 10) (1 1 1 1 1 1 1 1 1 1) > (define ar1 (ari 1 1)) ;��� 1 ���� 1 ���������� > (head ar1 10) (1 2 3 4 5 6 7 8 9 10) > (head (lazy-filter even? ar1) 10) (2 4 6 8 10 12 14 16 18 20)
fib(1) = 1 fib(2) = 1 fib(n+1) = fib(n) + fib(n-1)��ɽ��������Ǥ���lazy-cons �� lazy-map ��Ȥ��ȡ�[code 3] �˼����ͤˡ����ؾ������Τޤޤ� �����ɤ��ޤ��������� O(n) �Υ��������dzƹब������ޤ���[sample 3] ���ͤϽֻ��� ������ޤ���
[code 3]
01: (define fib 02: (lazy-cons 1 03: (lazy-cons 1 04: (lazy-map + fib (lazy-cdr fib)))))
> (head fib 20) (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765) > (lazy-ref fib 100) 573147844013817084101
a(n+1) = (a(n) + N/a(n)) / 2 (2)�⤷�����ζ��������˸��� a �˼�«����ʤ顢
a = (a + N/a) / 2 �������äơ� 2a = a + N/a a = N/a a*a = N a = squareroot(N)�Ȥʤꡢ�Τ��˶˸��� a �� N ��ʿ�����Ǥ��� (2) ����ꡢ�������������δؿ��ʤΤǡ�����ͤο���� inf-seq ��ɽ���ޤ��� ����ͤ� 1 �˸��ꤷ�ޤ����������ο���ϼ�«���ᤤ�Τ�����Ϥ���ޤ���
[code 4] ��ʿ���������ץ��������ޤ���
[code 4]
01: ;;; Newton-Raphson method 02: (define (newton-raphson n) 03: (inf-seq 1 (lambda (x) (/ (+ x (/ n x)) 2)))) 04: 05: ;;; returning a reasonable answer. 06: ;;; If the ratio of successive terms is in (1 - eps) and (1 + eps), 07: ;;; or the following term is zero, 08: ;;; the function returns it. 09: (define (lazylist->answer ls eps) 10: (let ((e1 (- 1.0 eps)) 11: (e2 (+ 1.0 eps))) 12: (let loop ((val (lazy-car ls)) 13: (ls1 (lazy-cdr ls))) 14: (let ((val2 (lazy-car ls1))) 15: (if (or (zero? val2) (< e1 (/ val val2) e2)) 16: (exact->inexact val2) 17: (loop val2 (lazy-cdr ls1))))))) 18: 19: ;;; 20: (define (my-sqrt n eps) 21: (lazylist->answer (newton-raphson n) eps))
> (my-sqrt 9 0.0000001)
3.0
�����ǡ�lazylist-diff �˼����褦�� ����� h0 ������Ƥ����ͤ�Ⱦʬ�ˤ��Ƥ����ٱ�ꥹ�� (geo h0 0.5) ���ꡢ ������б��������ͤ���ʬ�ꥹ�Ȥ���ޤ���
(lazylist->answer (lazylist-diff h0 f x) eps)��Ȥä���ľ���ͤ���Ƥ��ɤ��ΤǤ�������«���٤��Τǡ���«�������ؿ� super ��Ȥä� ��«�����ޤ��� ��«������ƥ��˥å��ˤĤ��Ƥ� �ʤ��ؿ��ץ�����ߥϽ��פ� �Ƥ��������� ��«���®�����륢�르�ꥺ��Ϥ���ʤ��ʣ���ǡ��̾��ȿ����Ȥä������ǥ��ǤϤ��ʤ���̤ˤʤ�ޤ��� �ٱ�ɾ����Ȥ��Ȥ��줬�����ؤ�����˶ᤤ���Ǵʷ��ɽ���Ǥ��ޤ����ޤ����ץ�����ब�⥸�塼�벽����Ƥ���Τ� ���Τޤ�¾�������Ŭ���Ǥ��ޤ���4.3.3. ��Ǽ���������ʬ�� [code 5] �Ǽ�������«��®�ؿ��Τޤ����Ѥ��Ƥ��ޤ���
[code 5]
01: ;;; differentiation 02: 03: ;;; primitive function for differentiation 04: (define (easydiff f x h) 05: (/ (- (f (+ x h)) (f x)) h)) 06: 07: ;;; create a lazy list of approximation for differentiation 08: (define (lazylist-diff h0 f x) 09: (lazy-map (lambda (h) (easydiff f x h)) (geo h0 0.5))) 10: 11: ;;; eliminate error from the approximation 12: (define (elimerror n ls) 13: (let ((a (lazy-car ls)) 14: (b (lazy-second ls)) 15: (c (expt 2 n))) 16: (lazy-cons 17: (/ (- (* b c) a) (- c 1)) 18: (elimerror n (lazy-cdr ls))))) 19: 20: ;;; estimate `n' in elimerror 21: (define (order ls) 22: (let* ((a (lazy-car ls)) 23: (b (lazy-second ls)) 24: (c (lazy-ref ls 2)) 25: (d (- (/ (- a c) (- b c)) 1.0))) 26: (cond 27: ((< d 2) 1) 28: ((<= 2 d 16) (inexact->exact (round (log2 d)))) 29: (else 4)))) 30: 31: ;;; 32: (define (log2 x) 33: (/ (log x) (log 2))) 34: 35: ;;; improve convergency of the lazy list of the approximation 36: (define (improve ls) 37: (elimerror (order ls) ls)) 38: 39: ;;; return the second value of the lazy list 40: (define (lazy-second ls) 41: (lazy-car (lazy-cdr ls))) 42: 43: ;;; further improve the convergency of the list 44: (define (super ls) 45: (lazy-map lazy-second (inf-seq ls improve))) 46: 47: 48: ;;; calculate the differentiation of function `f' at x within error eps 49: ;;; h0 is initial window width 50: (define (diff f x h0 eps) 51: (lazylist->answer (super (lazylist-diff h0 f x)) eps))
> (diff sin 0.0 0.1 0.0000001) 0.9999999999999516 > (diff exp 0.0 0.1 0.000001) 0.9999999991733471
�¹���˼����褦�������ư��ޤ���
[code 6]
01: ;;; integration 02: 03: ;;; primitive integration 04: (define (easyintegrate f a b) 05: (* (/ (+ (f a) (f b)) 2) (- b a))) 06: 07: ;;; create the lazy list of approximation for integration 08: (define (lazylist-integrate f a b) 09: (let ((mid (/ (+ a b) 2))) 10: (lazy-cons (easyintegrate f a b) 11: (lazy-map + (lazylist-integrate f a mid) 12: (lazylist-integrate f mid b))))) 13: 14: ;;; integrate function `f' in a range of `a' and `b' within error `eps' 15: (define (integrate f a b eps) 16: (lazylist->answer (super (lazylist-integrate f a b)) eps))
> (integrate sin 0 pi 0.0000001) 2.000000002272428 > (integrate exp 0 1 0.0000001) 1.7182818277724858 > (- (exp 1) 1) 1.718281828459045
�̾�Υץ���������ǤϷ����֤��Ϥ����Ѥι�ʸ��Ȥäƽ�ɬ�פ����ä��Τ� �ץ������Υ⥸�塼�벽�ˤϸ³�������ޤ����������ٱ�ɾ���ꥹ�Ȥ�Ȥ��� �ǡ����˷����֤��������Ȥ���������������뤳�Ȥ��Ǥ���Τǡ� �ץ�������ʷ�˽��Ȥ��Ǥ��ޤ���
�ٱ�ɾ���ˤĤ��Ƥ���˾ܤ����Τꤿ���ͤ� Haskell ��Ϣ�Υڡ����� google ��õ�äƤߤƤ�����������������ä����ۺ� Haskell �Τ��ٶ��⸫�ƤߤƤ���������
���Υڡ����Ǽ����������ɤ� ��Ͽ�ˤĤ��Ƥ����ޤ��Τǵ����������� ����������ɤ���ͷ��ǤߤƤ���������
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |