我对Haskell很陌生,我试图围绕Fibonacci序列的惰性表达如何工作。
我知道之前已经问过这个问题,但是没有一个答案解决了我对结果进行可视化的问题。
代码是使用zipWith
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
我理解以下内容:
zipWith
字面上将两个列表拉在一起tail
抓取列表中第一个元素thunks
。根据我的理解,它首先使用[0,1,<thunk>]
添加[1,<thunk>]
和zipWith (+)
来提供[1,<thunk>]
。所以现在你有了
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
我用谷歌搜索过的很多参考资料都已进入&#34;可视化&#34;上面的行为
fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
我的问题是:
为什么上面一行中的 fibs
组件只对应 [1,1,<thunk>]
而不是 {{1 } ?
不应该[0,1,1,<thunk>]
包含整个列表加上fibs
吗?
答案 0 :(得分:11)
此中间步骤错误,因为zipWith
已经处理了第一对项目:
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
回想一下zipWith在一般情况下的作用:
zipWith f (x:xs) (y:ys) = (f x y) : zipWith f xs ys
如果直接应用定义,则可以进行此扩展:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs) # fibs=[0,1,...]
= 0 : 1 : zipWith (+) [0,1,...] (tail [0,1,...]) # tail fibs=[1,...]
= 0 : 1 : zipWith (+) [0,1,...] [1,...] # apply zipWith
= 0 : 1 : (0+1 : zipWith (+) [1,0+1,...] [0+1,...])
= 0 : 1 : 1 : zipWith (+) [1,1,...] [1,...] # apply zipWith
= 0 : 1 : 1 : (1+1 : zipWith (+) [1,1+1,...] [1+1,...])
= 0 : 1 : 1 : 2 : zipWith (+) [1,2,...] [2,...] # apply zipWith
= 0 : 1 : 1 : 2 : (1+2 : zipWith (+) [2,1+2,...] [1+2,...])
= 0 : 1 : 1 : 2 : 3 : zipWith (+) [2,3...] [3,...] # apply zipWith
:
答案 1 :(得分:1)
如何看待正在发生的事情。
1 1 2 3 5 8 13 <----fibs
1 2 3 5 8 13 <----The tail of fibs
+________________ <----zipWith (+) function
2 3 5 8 13 21 <----New fibs. 13 drops out --nothing to zip with
finally, add [1, 1] to beginning
1, 1, 2, 3, 5, 8, 13, 21