1

map 的 Scheme 实现采用 N+1 个参数:一个包含 N 个参数的过程和 N 个列表。此外,当到达最短列表的末尾时,它会终止映射。

另一种方法是为每个列表提供一个默认值,如果结果比其他列表短,它将被视为每个列表的下一个元素。

那就是定义一个过程 streem-map 作为它的参数: N 个
参数的过程
N 个元素的列表,这是第 N 个流
N个流的默认值

流映射生成一个流,其中第一个元素是应用于流的 (N) 个第一个元素的过程,第二个元素是应用于流的第二个元素的相同过程,依此类推。如果第 N 个流变空,则 streem-map 使用第 N 个默认元素。因此,由 streem-map 产生的流永远是无限长的;如果所有 N 个输入流的长度都是有限的,最终它将生成由应用于 N 个默认值的过程组成的列表。

例如:

(streem-map (lambda (x y z) (* x y z))
‘(0 1 2)
(list->streem ‘(1 2 3))
(list->streem ‘(9 9))
(list->streem ‘(4))

将生成包含以下内容的无限流:'(36 36 6 0 0 0 ...)

4

2 回答 2

2

让我们首先定义一组基本流原语,以便其余代码有意义:

(define-syntax stream-cons
  (syntax-rules ()
    ((stream-cons obj expr)
     (cons obj (delay expr)))))

(define stream-car car)
(define (stream-cdr p) (force (cdr p)))
(define stream-null? null?)

有了这些,我们可以定义“流”的操作,我们的“更好的流”。

(define (streem-car stream default)
  (if (stream-null? stream) default (stream-car stream)))

(define (streem-cdr stream)
  (if (stream-null? stream) stream (stream-cdr stream)))

(define (streem-map proc defaults . streams)
  (stream-cons (apply proc (map streem-car streams defaults))
               (apply streem-map proc defaults (map streem-cdr streams))))

您应该能够轻松地将其调整为您已经在使用的任何流库。您不需要单独的 list->streem 转换,您可以传递 streem-map 常规流(大概是使用 list->stream 创建的)。

于 2009-05-04T06:24:48.727 回答
0

如果你使用SRFI-41的流,这只是stream-unfold. 注意:我是 SRFI-41 的作者。

于 2012-10-01T14:55:13.890 回答