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错误?

虚假的

首先,fib在红宝石版本中不等同于clojure版本。在clojure版本中,它是一个功能。

而且Enumerable#zipEnumerable#dropEnumerable.take没有偷懒,除非你明确的指定。如果您不调用Enumerable#lazy,它们将返回一个Array(急于消耗所有项目;导致异常)。

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]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章