Scheme 如何用生成器实现斐波那契?

Scheme 如何用生成器实现斐波那契?,scheme,Scheme,我试图实现生成器,在Scheme中生成斐波那契数的列表,但我做不到。 我有两个函数,第一个是以列表形式返回斐波那契数的函数,第二个是生成函数 我要做的是最终将斐波那契函数从斐波那契数列表转换成一个生成器 ;FIBONACCI NUMBERS (define (fib n a b i) (if (= i n) (list b) (cons b (fib n b (+ a b) (+ i 1))) ) ) (define (fibonacci n) (cond ((= n 1) (

我试图实现生成器,在Scheme中生成斐波那契数的列表,但我做不到。 我有两个函数,第一个是以列表形式返回斐波那契数的函数,第二个是生成函数

我要做的是最终将斐波那契函数从斐波那契数列表转换成一个生成器

;FIBONACCI NUMBERS
(define (fib n a b i)
 (if
  (= i n)
  (list b)
 (cons b (fib n b (+ a b) (+ i 1)))
 )
)
(define (fibonacci n)
 (cond
 ((= n 1) (list 1))
 (else (fib n 0 1 1))
 )
)

;GENERATOR
(define (generator start stop step)
  (let ((current (- start 1)))
  (lambda ()
  (cond ((>= current stop) #f)
  (else
   (set! current (+ current step))
    current)))))

(define (next generator)
 (generator))

当你编写
generators
时,人们会想到
generators
的概念,这在其他语言中很容易理解

现在,这有点像用迭代来制作一个步进器。它在上面有流和传感器。您可以创建映射函数,这些函数组成一系列操作,对每个项目进行计算,而不是像链接
map
那样在每个项目之间执行单独的过程,生成大量集合。自从早期版本的
await
async
是生成器和承诺的组合以来,JavaScript在过去几年中的一大亮点就是与生成器相关联

现在,如果你想在更一般的意义上,一个处理下一个值的过程。你也可以这样做:

(define fib 
  (let ((a 0) (b 1))
    (lambda ()
      (let ((result a))
        (set! a b)
        (set! b (+ result b))
        result))))

(fib) ; ==> 0
(fib) ; ==> 1
(fib) ; ==> 1
(fib) ; ==> 2
(fib) ; ==> 3

如您所见,这是通过更新私有绑定来完成契约的。这比那些花哨的真正的发电机更糟糕

既然西尔维斯特提到了溪流,这里有一个解决方案-

(define fib
  (stream-cons 0
               (stream-cons 1
                            (stream-add fib
                                        (stream-rest fib)))))


(stream->list (stream-take fib 20))
; '(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
流添加
将使用
+
和流原语将两(2)个流添加在一起-

(define (stream-add s1 s2)
  (if (or (stream-empty? s1)
          (stream-empty? s2))
      empty-stream
      (stream-cons (+ (stream-first s1)
                      (stream-first s2))
                   (stream-add (stream-rest s1)
                               (stream-rest s2)))))
或者,您可以采用更通用的方法,允许使用任何过程和任意数量的流-

(define ((stream-lift f) . s)
  (if (ormap stream-empty? s)
      empty-stream
      (stream-cons (apply f (map stream-first s))
                   (apply (stream-lift f) (map stream-rest s)))))

(define stream-add (stream-lift +))
(define ((stream-lift f) . s)
  (if (ormap stream-empty? s)
      empty-stream
      (stream-cons (apply f (map stream-first s))
                   (apply (stream-lift f) (map stream-rest s)))))

(define stream-add (stream-lift +))