我刚开始学习Haskell几个小时,试图理解这一点 The Fibonacci sequence确实:
fibs = 0 : 1 : next fibs
where
next (a : t@(b:_)) = (a+b) : next t
next
函数对我来说很奇怪,它最终会得到一些"无效"输入,就像起初一样:
next (0:1) = (0+1) : next [1]
但后来next ([1])
无法使用,因为t@(b:_)
中没有输入。那么next
如何运作?
我的下一个困惑是fib
本身,因为它假设是一个斐波那契序列,我假设在第一步之后会得到fibs = 0 : 1 : 1 : next fibs
但是我们需要计算next([0, 1, 1])
女巫给(0+1): next([1, 1])
== 1 : next([1, 1])
,我们得到初始元素1,所以在next([0, 1, 1])
中,列表的第一个值(在下一个文件中)将为1,但是将这个1附加到原始的fib上,我们得到的0 : 1 : 1 : 1
不是Fibonacci序列。
我认为我误解了某些东西,它实际上是如何运作的?
答案 0 :(得分:4)
定义递归定义结果的标准方法是从undefined
开始近似这样的值,并从那里展开递归,如下所示:
-- A function describing the recursion
f x = 0 : 1 : next x
fibs0 = undefined
fibs1 = f fibs0 = 0 : 1 : next undefined
-- next requires at least 2 elements
= 0 : 1 : undefined
fibs2 = f fibs1 = 0 : 1 : next fibs1
= 0 : 1 : next (0 : 1 : undefined)
= 0 : 1 : 1 : next (1 : undefined)
-- next requires at least 2 elements
= 0 : 1 : 1 : undefined
fibs3 = f fibs2 = 0 : 1 : next fibs2
= 0 : 1 : next (0 : 1 : 1 : undefined)
= 0 : 1 : 1 : next (1 : 1 : undefined)
= 0 : 1 : 1 : 2 : next (1 : undefined)
-- next requires at least 2 elements
= 0 : 1 : 1 : 2 : undefined
fibs4 = f fibs3 = 0 : 1 : next fibs3
= 0 : 1 : next (0 : 1 : 1 : 2 : undefined)
...
如果我们继续前进,我们将接近完整序列"在极限",逐步逼近它。这个非正式的论证可以通过克林的不动点定理正式证明。
答案 1 :(得分:0)
next
函数实际上会生成fibs
- 所以它不会调用next [0, 1, 1]
来调用next (0 : 1 : 1 : next rest)
。
图片中发生了什么:
fib = 0 : 1 : not-yet-evaluated-part
fib = 0 : 1 : [+] : not-yet-evaluated-part
^ ^ |
*---*----* (applying next to fib)
fib = 0 : 1 : 1 : [+] : not-yet-evaluated-part
^ ^ |
*---*----* (next calls itself)
fib = 0 : 1 : 1 : 2 : [+] : not-yet-evaluated-part
^ ^ |
*---*----* (etc)
next
是“铁路建设者列车”,需要一些初始轨道才能运行(0 : 1 :
...)。
因为有[]
- 列表的末尾无处放置在fibs列表中,它将无限。
但是,我建议你从不太模糊的事情开始 - 例如,你应该尝试单独理解列表。