nan*_*han 5 scheme stream sicp lazy-sequences racket
如何在Scheme中通过流映射定义整数:
(定义整数(stream-cons 1(stream-map * something * * something *)))
(define integers
(stream-cons 1
(stream-map add1 integers)))
Run Code Online (Sandbox Code Playgroud)
有关流的更多信息,请参阅SRFI-41 。
@user448810 的答案是完美的,它将在 Racket 中工作(它使用 Racket 特定的程序)。但这个问题也被标记为SICP,所以这是我的两分钱。
仅使用 SICP 中可用的 Scheme 过程的子集来回答问题会产生等效但略有不同的解决方案,仅使用书中定义的以下原始流操作:stream-null? stream-cons stream-car stream-cdr。特别要注意的是,这stream-map不是Scheme的标准部分,在书中它是根据原始操作来实现的,比Racket的实现有一个优势——它可以接收可变数量的流作为参数:
(define (stream-map proc . args)
(if (stream-null? (car args))
the-empty-stream
(stream-cons (apply proc (map stream-car args))
(apply stream-map (cons proc (map stream-cdr args))))))
(define (add-streams s1 s2)
(stream-map + s1 s2))
Run Code Online (Sandbox Code Playgroud)
有了上面的过程,就很容易定义integers
(define ones (stream-cons 1
ones))
(define integers (stream-cons 1
(add-streams ones integers)))
Run Code Online (Sandbox Code Playgroud)
实际上,stream-map上面的过程受到一个错误的影响,如果我们向它提供两个流,其中第二个比第一个短,这个错误就会变得明显,如下所示:
(define (stream-map proc . args)
(if (stream-null? (car args))
the-empty-stream
(stream-cons (apply proc (map stream-car args))
(apply stream-map (cons proc (map stream-cdr args))))))
(define (add-streams s1 s2)
(stream-map + s1 s2))
Run Code Online (Sandbox Code Playgroud)
建议的实现stream-map将采用 的 else 分支if,因为(stream-null? (car args))is(stream-null? (cons-stream 1 the-empty-stream))为 false,因此它将尝试评估,(map stream-car args)而后者又会尝试评估(stream-car the-empty-stream),从而导致运行时失败。
以下是该过程的可能修复stream-map:
(define ones (stream-cons 1
ones))
(define integers (stream-cons 1
(add-streams ones integers)))
Run Code Online (Sandbox Code Playgroud)