あなたの問題は、あなたがあなたの抽象的なふるいをどのように使っているかについて一貫していないということです。
ふるいは次のように定義されていますか?
;; A Sieve is a (cons n p), where
;; n is a Natural Number
;; p is a Procedure that takes no arguments and returns a Sieve
またはそれはこのように定義されていますか
;; A Sieve is a (list n p), where
;; n is a Natural Number
;; p is a Procedure that takes no arguments and returns a Sieve
コード内のいくつかの場所では、pを抽出し、次のように呼び出してい
((cdr st))
ます。このような他の場所では:((cadr st))
あなたの質問のコメント投稿者がそれらのそれぞれに個別に質問をしている理由は、あなたがふるいを形成し、ふるいからサブパーツを抽出するための規則が何であるかについての高レベルの定義を与えていないからです。上記のようなデータ定義はこれに役立ちます。
私にとっては、データ定義とコントラクトを追加し、関数を個別にテストし始めた後、すぐに問題を見つけました。((cdr st))
(ヒント:これは、上記と((cadr st))
上記の不一致と関係があります。)
これが私のバージョンのコードです。Sieve表現の選択を、抽象的なインターフェイスの背後に隠すことでローカライズします。ストリームコンストラクターが受け取る式の評価を遅らせたいので、マクロを使用してこれを行いました(ただし、インターフェイスを変更することでこれを回避できるため、Sieveコンストラクターは直接式ではなくsieve生成プロシージャを実行する必要がありました) 。
読者のための演習:現在のAPIを使用していて、誰かがこのコードで指定したデータ定義に従っている場合、stream-empty?
trueを返すことはできません。どうやってこれを証明できますか?
;; A Stream is a (list Nat (-> () Stream))
;; but this knowledge should not be used anywhere but in the
;; procedures (and special form) stream-rest, stream-first, stream,
;; and stream-empty?.
;; stream-rest: Stream -> Stream
(define (stream-rest st) ((cadr st)))
;; stream-first: Stream -> Nat
(define (stream-first st) (car st))
;; Special Form: (stream <natural-number> <stream-expr>) is a Stream
(define-syntax stream
(syntax-rules ()
((stream n expr) (list n (lambda () expr)))))
;; Stream -> Boolean
(define (stream-empty? st) (null? st))
;; Nat -> Stream
(define (int-builder$ x)
(stream x (int-builder$ (+ 1 x))))
;; Nat Stream -> [Listof Nat]
(define (take$ m st)
(if (or (= m 0) (stream-empty? st))
'()
(cons (stream-first st) (take$ (- m 1) (stream-rest st)))))
;; Nat Stream -> Stream
(define (filter-out-mults$ num st)
(cond
(( = (remainder (stream-first st) num) 0)
(filter-out-mults$ num (stream-rest st)))
(else
(stream (stream-first st) (filter-out-mults$ num (stream-rest st))))))
;; Stream -> Stream
(define (sieve$ st)
(stream (stream-first st)
(sieve$ (filter-out-mults$ (stream-first st) (stream-rest st)))))
;; Nat -> [Listof Nat]
(define (stol$ n)
(take$ n (sieve$ (int-builder$ 2))))