我正在编写一个斐波那契数列生成器,我试图理解Haskell中的以下代码:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
我知道什么是zipWith,但我不确定程序如何执行以及为什么它确实生成所有斐波那契数。我试图使用函数式语言中的环境概念来理解为什么它不会终止:
最初,由于Haskell的惰性求值,中的绑定应该是fibs: [1,1,x],然后要计算fibs,解释器首先需要计算x,这种情况下x是zipWith (+) fibs (tail fibs)。在计算zipWith时,它得到fibs:[1,1,2,x],再次由于Haskell的惰性求值。此时,中的fibs绑定到[1,1,2,x]。但是,为了完全计算fibs,它继续计算x,我们回到了之前的步骤。
这样说是否正确?
此外,我注意到,当我在ghci中运行上面的程序时,它立即提示当前已计算的斐波那契序列,为什么?它不应该在完成所有计算后再打印结果吗?
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
我知道什么是zipWith,但我不确定程序如何执行以及为什么它确实生成所有斐波那契数。我试图使用函数式语言中的环境概念来理解为什么它不会终止:
最初,由于Haskell的惰性求值,中的绑定应该是fibs: [1,1,x],然后要计算fibs,解释器首先需要计算x,这种情况下x是zipWith (+) fibs (tail fibs)。在计算zipWith时,它得到fibs:[1,1,2,x],再次由于Haskell的惰性求值。此时,中的fibs绑定到[1,1,2,x]。但是,为了完全计算fibs,它继续计算x,我们回到了之前的步骤。
这样说是否正确?
此外,我注意到,当我在ghci中运行上面的程序时,它立即提示当前已计算的斐波那契序列,为什么?它不应该在完成所有计算后再打印结果吗?
print
,它可以惰性地消耗列表,打印每个可用的元素。你定义的fibs
列表实际上是无限的,你无法计算整个列表。 - bheklilr