SICP 読み (132) 3.5.2 無限ストリーム

問題 3.55

現実トウヒ中にちょろっと考えてメモを残している。こんな感じ。

(cons-stream (stream-car s)
             (add-streams (stream-cdr s)
			  自分))

合ってるのかなぁ。例示されてる fib とか integers とかも_自分_なんですが partial-sums は引数付きの手続きなんだよなぁ、と。
で、ヒラメいたのが let 使ったらどうか、という事。文法的にはセイフなはずなんですが今から確認を。

確認

let では失敗。とりあえず動いた実装と試験が以下。

#!/usr/bin/env gosh

(use test.unit)
(require "3.5.1")

(define-test-suite "3.5.1"

  ("partial-sums"
   ("integers"
    (let ((s (partial-sums integers)))
      (assert-equal 1 (stream-ref s 0))
      (assert-equal 3 (stream-ref s 1))
      (assert-equal 6 (stream-ref s 2))
      (assert-equal 10 (stream-ref s 3))
      (assert-equal 15 (stream-ref s 4))
      )
    )
   )
  )

次は実装。partial-sums のみ。

(define (partial-sums s)
  (define x (cons-stream (stream-car s)
			 (add-streams (stream-cdr s)
				      x)))
  x)

define じゃないと駄目なのかなぁ。最初以下なカンジで試したら怒られた。

(define (partial-sums s)
  (let ((x (cons-stream (stream-car s)
			(add-streams (stream-cdr s)
				     x))))
    x))

unbound variable x だそうで。他に方法は無いんだろうか。

追記

letrec というのがあった。なるほど。

(define (partial-sums s)
  (letrec ((x (cons-stream (stream-car s)
			   (add-streams (stream-cdr s)
					x))))
    x))

上記実装でも試験はパスしている模様。