想逐步了解Haskell中的以下功能
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
我了解到,“小故障”通常是“懒惰的”,因此下一项将“按需”计算,但是我不确定“尾部”函数如何在无限列表上工作。
因此,说明它如何与一些中间数据一起使用将很有帮助。
最佳答案
一开始,评估是这样的:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
如果我们用评估替换
fibs
,它看起来像这样:fibs = 0 : 1 : zipWith (+) (0 : 1 : ?) (1 : ?)
其中
?
表示未评估的thunk。让我们评估fibs
的下一个元素:fibs = 0 : 1 : zipWith (+) (0 : 1 : ?) (1 : ?) ==>
fibs = 0 : 1 : 1 : zipWith (+) (1 : ?) (?)
使用了
zipWith
的每个参数列表的第一个元素。现在,当我们评估它时,我们也知道下一个thunk的值是什么,我们可以填充它。这使我们可以评估下一个单元格,依此类推:fibs = 0 : 1 : 1 : zipWith (+) (1 : ?) (?) ==>
fibs = 0 : 1 : 1 : zipWith (+) (1 : 1 : ?) (1 : ?) ==>
fibs = 0 : 1 : 1 : 2 : zipWith (+) (1 : ?) (?) ==>
fibs = 0 : 1 : 1 : 2 : zipWith (+) (1 : 2 : ?) (2 : ?) ==>
fibs = 0 : 1 : 1 : 2 : 3 : zipWith (+) (2 : ?) (?) ==>
...