标签: haskell
我想知道执行
factorial 0 = 0 factorial n = n * factorial (n-1)
和
factorial 0 r = r factorial n r = factorial (n-1) (r * n)
哪个更有效率?
答案 0 :(得分:3)
我也不确定。第一个将在模式测试中将n-1评估为0,但会产生一系列乘法,这些乘法在达到0之前无法开始执行。第二个将产生存储在r参数中的相同堆栈。然而,第二个优点是你可以使r参数严格并且在常量空间中纯粹是尾递归,因为它的乘法顺序与调用顺序一致。
n-1
0
r
我们可以将第一个版本解释为factorial n = foldr (*) 1 [n,n-1..1],将第二个版本解释为factorial n = foldl (*) 1 [n,n-1..1]。因此r严格性的差异与foldl和foldl'之间的差异相同。但是如果列表很长并且操作可以通过不检查第二个参数来快捷方式,则foldr版本具有明显的优势。
factorial n = foldr (*) 1 [n,n-1..1]
factorial n = foldl (*) 1 [n,n-1..1]
foldl
foldl'
foldr