如何在方案中通过流映射定义整数:
(定义整数(流缺点 1 (流映射 *某物* *某物*))
(define integers
(stream-cons 1
(stream-map add1 integers)))
有关流的更多信息,请参阅 SRFI-41。
@user448810的答案是完美的,它将在球拍中工作(它使用特定于球拍的程序)。但是这个问题也标有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))
完成上述过程后,可以轻松定义integers
(define ones (stream-cons 1
ones))
(define integers (stream-cons 1
(add-streams ones integers)))
<小时 />实际上,上面的stream-map
过程受到一个错误的影响,如果我们向它提供两个流,其中第二个流比第一个短,它就会变得适用,如下所示:
(stream-map + (cons-stream 1 the-empty-stream) the-empty-stream)
stream-map
的提议实现将采用if
的else分支,因为(stream-null? (car args))
是(stream-null? (cons-stream 1 the-empty-stream))
,这是假的,因此它将尝试评估(map stream-car args)
,而又会尝试评估(stream-car the-empty-stream)
,导致运行时失败。
以下是stream-map
过程的可能修复方法:
(define (any . args) ; takes any numer of booleans and or-s them together
(if (null? args)
#f
(or (car args) (apply any (cdr args)))))
(define (stream-map proc . args)
(if (apply any (map stream-null? args))
the-empty-stream
(cons-stream (apply proc (map stream-car args))
(apply stream-map (cons proc (map stream-cdr args))))))
您也可以使用 SICP 中的示例:
(define (integers-starting-from n)
(cons-stream n (integers-starting-from (+ n 1))))
(define nats (integers-starting-from 1))