Haskell如何评估Fibonacci函数?

时间:2015-03-15 13:30:59

标签: haskell recursion fibonacci reduction

我目前在Haskell中查看此函数,该函数返回位置n的斐波那契数

fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

现在,它编译,返回正确的结果和所有内容......但我没有看到Haskell如何评估此函数。

Haskell是否总是寻找合适的定义然后应用该定义直到它不再存在(例如达到基本情况)?

在这种情况下,这就是我想出的。例如,评估fib 3

fib n = fib (n-1) + fib (n-2)
fib 3 = fib (3-1) + fib (3-2)
fib 3 = fib ((3-1)-1) + fib ((3-1)-2) + fib ((3-2)-1) + fib ((3-2)-2)
fib 3 = fib (((3-1)-1)-1) + fib (((3-1)-1)-2) +
        fib (((3-1)-2)-1) + fib (((3-1)-2)-2) + 
        fib (((3-2)-1)-1) + fib (((3-2)-1)-2) + 
        fib (((3-2)-2)-1) + fib (((3-2)-2)-2)
...

这可以在没有给出实际结果的情况下永远持续下去。但是,Haskell返回一个结果。那么我做错了什么?

1 个答案:

答案 0 :(得分:4)

定义中方程的顺序很重要。

部分

fib n = fib (n-1) + fib (n-2)
仅当前一行不适用时才会应用

。也就是说,仅当n不是01时。正因为如此,这一步

fib 3 = fib (3-1) + fib (3-2)
fib 3 = fib ((3-1)-1) + fib ((3-1)-2) + fib ((3-2)-1) + fib ((3-2)-2)

错误:fib (3-2)fib 1 = 1,而非fib ((3-2)-1) + fib ((3-2)-2)

另一种观察方式如下。 整个3行定义可以使用case等效表示为

fib n = case n of
        0 -> 0
        1 -> 1
        m -> fib (m-1) + fib (m-2)