一个初学者的问题。我对以下内容有点困惑:我读到 GHC(Haskell 的?)惰性评估方法包括使用共享,例如评估表达式
(1+1)*(1+1)
只会计算1+1
一次。在 Graham Hutton 所著的“用 Haskell 编程”一书中,解释说这是通过用1+1
指向它的一个副本的指针替换出现的两个并仅评估那个副本来实现的。
但是计算第 n 个斐波那契数fib n = if (n<2) then n else fib (n-1) + fib(n-2)
需要 n 中的指数时间。我对上述内容的理解告诉我,例如fib 5
将被这样评估:
fib 5 => fib 4 + fib 3 => fib 3 + fib 2 + fib 3 => x + fib 2 + x
和x = fib 3 = fib 2 + fib 1 = y + fib 1
所以fib 5 = y + fib 1 + y + y + fib 1
和y = fib 2 = fib 1 + fib 0 = 1
所以fib 5 = 1 + 1 + 1 + 1 + 1
其中x
和y
被作为共享值引入。
fib k
但是这种处理方式虽然比迭代生成for的标准方式效率稍低,但2<=k<=n
显然不会像评估函数那样导致运行时间如此之长。那么我的理解有什么问题呢?