プロンプトの表示などでちょっと長いけれど載せちゃう.
delay, cons-streamはマクロで定義しなければいけないところではまった.
naoya_tさんのstream.scmを見て救われた.
;;exercise3.50 (define (stream-map proc . argstreams) (if (stream-null? (car argstreams)) the-empty-stream (cons-stream (apply proc (map stream-car argstreams)) (apply stream-map (cons proc (map stream-cdr argstreams)))))) ;;section3.5.1 (load "./stream2.scm") ;without memo-proc (load "./stream.scm") ;with memo-proc (display-stream (stream-enumerate-interval 0 10)) (define (enumerate-interval low high) (if (> low high) '() (cons low (enumerate-interval (+ low 1) high)))) ;;exercise3.51 (define (show x) (display-line x) x) (define x (stream-map show (stream-enumerate-interval 0 10))) ;;with memo-proc (stream-ref x 5) ;=> ;1 ;2 ;3 ;4 ;55 (stream-ref x 7) ;6 ;77 ;;without memo-proc (stream-ref x 5) ;=> ;1 ;2 ;3 ;4 ;55 (stream-ref x 7) ;=> ;1 ;2 ;3 ;4 ;5 ;6 ;77 ;前の結果が使えないので,すべて計算しなおす
- 3.52
memo-procを使わないと結果がおかしくなってしまうのは,accumの計算の元となるsumの値がおかしくなってしまうから.
そのため,memo-procを使うdelayで
(stream-ref 7)
を,何度行っても同じ値が帰ってくるが,memo-procを使わないdelayでそれをやると実行するたびに値が変わってしまう.
;;exercise3.52 ;;通常版 (use srfi-1) (define sum 0) (define (accum x) (set! sum (+ x sum)) sum) (define seq (map accum (enumerate-interval 1 20))) ;=> (1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210) (define y (filter even? seq)) ;=>(6 10 28 36 66 78 120 136 190 210) (define z (filter (lambda (x) (= (remainder x 5) 0)) seq)) ;=>(10 15 45 55 105 120 190 210) ;;stream版(with memo-proc) (define sum 0) (define (accum x) (set! sum (+ x sum)) sum) (define seq (stream-map accum (stream-enumerate-interval 1 20))) seq ;=> (1 . #<closure (memo-proc memo-proc)>) sum ;=> 1 (define y (stream-filter even? seq)) y ;=> (6 . #<closure (memo-proc memo-proc)>) sum ;=> 6 (define z (stream-filter (lambda (x) (= (remainder x 5) 0)) seq)) z ;=> (10 . #<closure (memo-proc memo-proc)>) sum ;=> 10 (stream-ref y 7) ;=> 136 (stream-ref y 3) ;=> 36 (display-stream z) ;=> ;10 ;15 ;45 ;55 ;105 ;120 ;190 ;210done sum ;=> 210 ;;stream版(without memo-proc) (define sum 0) (define (accum x) (set! sum (+ x sum)) sum) (define seq (stream-map accum (stream-enumerate-interval 1 20))) seq ;=> (1 . #<closure (stream-map stream-map)>) sum ;=> 1 (define y (stream-filter even? seq)) y ;=> (6 . #<closure (stream-filter stream-filter)>) sum ;=> 6 (define z (stream-filter (lambda (x) (= (remainder x 5) 0)) seq)) z ;=> (15 . #<closure (stream-filter stream-filter)>) sum ;=> 15 (stream-ref y 7) ;=> 162 (stream-ref y 3) ;=> 54 (display-stream z) ;=> ;15 ;180 ;230 ;305done sum ;=> 362