Stream 交替使用两个值

Stream 交替使用两个值,stream,scheme,racket,lazy-sequences,Stream,Scheme,Racket,Lazy Sequences,我有密码 (define alternate (letrec ([f (lambda (x) (cons x (lambda () (f (+ x 1)))))]) (lambda () (f 1)))) 结果是1,2,3。。 我怎么能把它改成1,2,1,2,1,2 我试过f区的犯人,但没有成功。 有什么想法吗?这很容易通过以下方式实现: 这里的诀窍是,流是使用来构建的,这基本上完成了手工实现的工作:它创建一个列表,其中的元素是“承诺”,只有在需要时才进行评估 stream cons生成一个惰

我有密码

(define alternate
(letrec ([f (lambda (x) (cons x (lambda () (f (+ x 1)))))])
(lambda () (f 1))))
结果是1,2,3。。 我怎么能把它改成1,2,1,2,1,2

我试过f区的犯人,但没有成功。
有什么想法吗?

这很容易通过以下方式实现:

这里的诀窍是,流是使用来构建的,这基本上完成了手工实现的工作:它创建一个列表,其中的元素是“承诺”,只有在需要时才进行评估

stream cons
生成一个惰性流,其中stream首先强制对第一个expr进行求值以生成流的第一个元素,stream rest强制对rest expr进行求值以为返回流的其余部分生成流

这显示了
alternate
如何返回形式为
12…

(define alt (alternate))

(stream-ref alt 0)
=> 1
(stream-ref alt 1)
=> 2
(stream-ref alt 2)
=> 1
(stream-ref alt 3)
=> 2
或者,如果您需要序列中n个元素的列表,请使用此程序,顺便说一下,它首先应该是Racket的一部分:

(define (stream-take s n)
  (if (zero? n)
      '()
      (cons (stream-first s)
            (stream-take (stream-rest s) (sub1 n)))))
现在它如预期的那样工作:

(define alt (alternate))

(stream-take alt 0)
=> '()
(stream-take alt 1)
=> '(1)
(stream-take alt 2)
=> '(1 2)
(stream-take alt 3)
=> '(1 2 1)

以下是对现有代码的一个小修改:

(define alternate
  (letrec ([f (lambda (x) (cons x (lambda () (f (if (= x 1) 2 1)))))])
    (lambda () (f 1))))

您可能还发现生成器很有用:

更新:

更好的方法是使用无限生成器:

Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom].
> (require racket/generator)
> (define g (infinite-generator (yield 1) (yield 2)))
> (g)
1
> (g)
2
> (g)
1
> (g)
2

我使用一个函数来调用流n次。如果我调用它一次,我想'(1)。第二次:'(12)第三次:'(12)第四次:'(12)这个流不是这样工作的:(@Rea通过我的实现很可能得到这个结果,请查看我的更新答案以获得解决方案这是家庭作业还是考试工作?!
Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom].
> (require racket/generator)
> (define g (generator () (let LOOP () (yield 1) (yield 2) (LOOP))))
> (g)
1
> (g)
2
> (g)
1
> (g)
2
Welcome to DrRacket, version 5.3.3.5 [3m].
Language: racket [custom].
> (require racket/generator)
> (define g (infinite-generator (yield 1) (yield 2)))
> (g)
1
> (g)
2
> (g)
1
> (g)
2