【问题标题】:How to make a better mapper in Scheme using Streams如何使用 Streams 在 Scheme 中制作更好的映射器
【发布时间】:2009-02-18 01:56:46
【问题描述】:

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

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

这就是定义一个以参数为参数的过程流图:
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 ...)

【问题讨论】:

    标签: stream scheme


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-08
        • 2018-01-01
        • 2023-03-14
        • 2019-10-23
        • 1970-01-01
        • 2016-05-27
        • 1970-01-01
        • 2018-12-16
        相关资源
        最近更新 更多