【问题标题】:How does Haskell evaluate the Fibonacci function?Haskell 如何评估斐波那契函数?
【发布时间】:2015-05-17 15:26:20
【问题描述】:

我目前正在查看 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 返回一个结果。那我做错了什么?

【问题讨论】:

    标签: haskell recursion fibonacci reduction


    【解决方案1】:

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

    部分

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

    仅在前面的行不适用时才应用。也就是说,仅当n 既不是0 也不是1 时。正因为如此,步骤

    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)
    

    【讨论】:

    • 谢谢,gets applied only when the previous lines do not apply 部分让我明白了
    猜你喜欢
    • 2017-12-06
    • 2015-01-06
    • 2014-05-03
    • 2011-02-17
    • 2018-07-03
    • 1970-01-01
    • 2017-01-08
    • 2019-12-03
    相关资源
    最近更新 更多