如何使用Streams在Scheme中制作更好的映射器

时间:2009-02-18 01:56:46

标签: stream scheme

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

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

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

Streem-map生成一个流,其中第一个元素是应用于流的第(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 ...)

2 个答案:

答案 0 :(得分: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?)

通过这些我们可以定义“streems”的操作,我们的“更好的流”。

(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创建的)。

答案 1 :(得分:0)

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