方案中的流 - 通过方案中的流映射定义整数



如何在方案中通过流映射定义整数:

定义整数(流缺点 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))

相关内容

  • 没有找到相关文章

最新更新