结构递归与尾递归的效率

时间:2017-11-17 16:22:17

标签: haskell

我想知道执行

之间的区别
factorial 0 = 0
factorial n = n * factorial (n-1)

factorial 0 r = r
factorial n r = factorial (n-1) (r * n)

哪个更有效率?

1 个答案:

答案 0 :(得分:3)

我也不确定。第一个将在模式测试中将n-1评估为0,但会产生一系列乘法,这些乘法在达到0之前无法开始执行。第二个将产生存储在r参数中的相同堆栈。然而,第二个优点是你可以使r参数严格并且在常量空间中纯粹是尾递归,因为它的乘法顺序与调用顺序一致。

我们可以将第一个版本解释为factorial n = foldr (*) 1 [n,n-1..1],将第二个版本解释为factorial n = foldl (*) 1 [n,n-1..1]。因此r严格性的差异与foldlfoldl'之间的差异相同。但是如果列表很长并且操作可以通过不检查第二个参数来快捷方式,则foldr版本具有明显的优势。