我对Haskell还比较新,试图理解Fibonacci数列的惰性表达方式。
我知道这个问题以前已经问过了,但是没有一个答案涉及到我遇到的可视化结果的问题。
代码使用 zipWith
是标准的。
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
我理解如下:
zipWith
直接将两个列表合并成一个列表。tail
获取除了列表中第一个元素以外的所有元素。- Haskell将“待计算”数据称为
thunks
。
从我的理解来看,它首先使用 zipWith (+)
将 [0,1,<thunk>]
和 [1,<thunk>]
相加,得到 [1,<thunk>]
。现在你有:
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
我搜索到的很多参考资料都会将上面这行代码“可视化”为:
fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
我的问题是:
为什么在上面一行中,fibs组件只对应于
[1,1,<thunk>]
而不是[0,1,1,<thunk>]
?
fibs
不应该包含整个列表和<thunk>
吗?
fibs = 0 : 1 : 1 : zipWith (+) (drop 1 $ fibs) (drop 1 $ tail fibs)
,因为此时我们已经沿着列表前进了一步。这就是你问题的答案所在。 - Will Ness