ストリームは本当に変異状態の置換ではありません。それは評価を遅らせる方法です。
例:
(define one-to-million
(let loop ((n #e1e6) (acc '()))
(if (zero? n)
acc
(loop (- n 1) (cons n acc)))))
(define (list-square lst)
(map (lambda (x) (* x x)) lst))
(define (list-double lst)
(map (lambda (x) (+ x x)) lst))
(define (list-sqrt lst)
(map sqrt lst))
(take (list-sqrt (list-double (list-square one-to-million))) 5)
; ==> (1.4142135623730951 2.8284271247461903
; 4.242640687119285 5.656854249492381 7.0710678118654755)
あなたがここにhappnes何を見れば、あなたはそれが道の各ステップで百万個の要素の新しいリストを作成し、最終的にはちょうど最初に使用していることがわかります5結果ストリームのバージョン:このバージョンで
(define (stream-take s n)
(if (zero? n)
'()
(cons (stream-car s)
(stream-take (stream-cdr s) (- n 1)))))
(define (integers-starting-from n)
(stream-cons n (integers-starting-from (+ n 1))))
(define from1 (integers-starting-from 1)) ; infinite stream!
(define (stream-map proc stream)
(stream-cons (proc (stream-car stream))
(stream-map proc (stream-cdr stream))))
(define (stream-square stream)
(stream-map (lambda (x) (* x x)) stream))
(define (stream-double stream)
(stream-map (lambda (x) (+ x x)) stream))
(define (stream-sqrt stream)
(stream-map sqrt stream))
(stream-take (stream-sqrt (stream-double (stream-square from1))) 5)
; ==> (1.4142135623730951 2.8284271247461903
; 4.242640687119285 5.656854249492381 7.0710678118654755)
第二の要素の二乗を開始する前に、それは結果の最初の要素のための各ステップを行うだろうが、あなたは最初の正方形を行うかのようにプログラムfoの構造が見え、ダブルなど。
おそらく現代のアプローチはリストを使用していますが、各要素のためのすべてのステップは熱心にトランスデューサとジェネレータです。
状態を維持するために、ストリームを必要としません。今、私たちはこれを完全に機能の実装を与えることができます
(let loop ((state '()) (input input))
(if (input-empty? input)
state ; finished
(loop (process-input (input-get input) state)
(input-next input))))
:
(define input '(1 2 3 4))
(define input-get car)
(define input-next cdr)
(define input-empty? null?)
(define process-input cons)
それとも、我々はそれ汚い副作用バージョン作ることができます:
(define input (current-input-port))
(define input-get read-line)
(define input-next values) ; just return the port
(define input-empty? (lambda (x) (eq? (peek-byte x) eof))) ; check if there is more to read
(define process-input cons)
あなたはそれが終了されるまで再帰的手続きを行うことができます
私はSICPでstream-consが特別な形式でなければならないことを発見しました。私の質問を修正してみましょう:金額ストリームを構築する適切な方法は何ですか?また、ユーザーが新しい引き出しを入力している間、機能的な方法でストリームを引き出すためにこのストリームが使用される典型的な方法を見たいと思います。私はまだ地方の州を避けるためにストリームを使う上での重要な要素を見ない。 –