Racket中的流

8

有人能帮我更好地理解如何编写流吗?

我知道流是一系列无限的值,编程时我学习的方法是将它们表示为一个惰性求值函数,当调用时会产生一个二元组:(1) 序列中的第一个元素和 (2) 代表第二个到无穷多个元素的流的惰性求值函数。

例如:

(define powers-of-two
    (letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
        (lambda () (f 2))))

我理解这里只是在生成2的幂,并且要访问它们,例如调用(car(powers-of-two))会得到2,调用(car((cdr(powers-of-two))))会得到4 现在我正在尝试编写一个名为red-blue的流,它在redblue字符串之间交替,但是我有点困惑如何构建它。

恭喜你完成了!请查看http://c2.com/cgi/wiki?SieveOfEratosthenesInManyProgrammingLanguages中的Scheme部分,以获取SICP风格流的工作示例。那里只有一个宏规则,您可以手动应用它。 - Will Ness
4个回答

14

看起来你正在询问如何使用thunks构建自己的自定义流,其他人已经回答了这个问题。但是为了保险起见,值得注意的是Racket内置了一个流库,大多数Racket程序员都会使用它来处理流。

下面是一个例子:

#lang racket
(require racket/stream)
(define reds (stream-cons "red" reds))
(define red-blues (stream-add-between reds "blue"))

;; show ten of them
(for ([i 10] [e (in-stream red-blues)])
  (displayln e))

6
对于Scheme中流的一般理解,我建议阅读SICP书中的第3.5节§3.5 Streams。它将教授您解决与流相关问题的基本概念,例如问题中提到的那个。
关于问题,以下是解决它的一般思路:
  • 构建两个无限流,一个仅产生字符串"red",另一个为"blue"
  • 组合两个流,从一个流中取一个元素,然后从另一个流中取一个元素(交替进行),这个过程称为SICP中的interleave

6

我写了SRFI-41,其中描述了流、提供了实现,并给出了许多例子。那里的流与SICP中的流不同,在SRFI中有一种“更好”的方式进行解释。


1

我是一个新手,但以下解决方案似乎也可以起作用:

 (define red-then-blue
   (letrec ([f (lambda (x) (cons x(lambda ()(f(cond [(string=? x "red") "blue"]
                                              ["red"])))))])
   (lambda () (f "red"))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接