提高Haskell的递归效率

时间:2018-07-21 19:34:03

标签: performance haskell recursion

使用此功能:

e :: Integer -> Integer -> Integer
e _ 1 = 1 
e n m 
 |n == m = e n (n-1) 
 |otherwise = e (n-1) m + e n (m-1)

如果我在GHCI中运行它,则第一次评估将花费大量时间,e 20 1大约需要10秒,但是此后,对更大数字的调用就大大减少了,大约为0.25秒。我认为正在发生某种缓存?

我有点明白为什么会爆炸,因为每个对e n m的调用都会再进行两个调用,然后每个都进行两个调用,依此类推。因此,求值的数量最终会变得非常大,但是其中很多都是相同的引用。

无论如何,Haskell是否可以实现这种功能,就像某种自动查找表一样?

1 个答案:

答案 0 :(得分:3)

GHC不会神奇地生成用于记忆的查找表。就是说,有些库使这变得容易得多。正如@AJFarmar建议的那样,您可以使用memoize软件包。

import Data.Function.Memoize

e :: Integer -> Integer -> Integer
e = memoFix2 $ \rec -> let e' _ 1 = 1
                           e' n m | n == m = rec n (n-1)
                                  | otherwise = rec (n-1) m + rec n (m-1)
                       in e'