Ruby中的懒惰斐波那契

我可以在Clojure中写一个懒惰的斐波那契,如下所示:

(def fib (lazy-cat [1 1] (map +' fib (rest fib)))) 

我正在尝试(不成功)在Ruby中编写它,如下所示:

 fib = Enumerator.new do |yielder| yielder << 1 << 1 fib.zip(fib.drop(1)).map do |a,b| yielder << (a + b) end end 

在简化的情况下,这适用:

 fib = Enumerator.new do |yielder| yielder << 1 << 1 puts "here" end puts fib.take(2).inspect puts fib.drop(1).take(1).inspect 

但这不是:

 fib = Enumerator.new do |yielder| yielder << 1 << 1 puts "here" fib.drop(1) end puts fib.take(2).inspect puts fib.drop(1).take(1).inspect 

为什么最后一个例子给我一个SystemStackError: stack level too deep错误?

首先,ruby版本中的fib不等同于clojure版本。 在clojure版本中,它是一个function。

除了明确指定它之外, Enumerable#drop Enumerable#zipEnumerable#dropEnumerable.take不是延迟的。 如果你不调用Enumerable#lazy ,它们会返回一个数组(急切地消耗所有项目;导致exception)。

 def fib Enumerator.new do |yielder| yielder << 1 << 1 fib.lazy.zip(fib.lazy.drop(1)).each do |a,b| yielder << a + b end end end fib.take(2) # => [1, 1] fib.lazy.drop(1).take(1).to_a # Note: `lazy`, `to_a`. # => [1] fib.take(4) # => [1, 1, 2, 3]