Functional programming 与递归相比,尾部递归的优点是什么

Functional programming 与递归相比,尾部递归的优点是什么,functional-programming,ocaml,Functional Programming,Ocaml,所以tailrecursive意味着一个递归函数,它在主体中使用一个递归调用。此外,它是最外层的,这意味着递归调用不在语句内部,而是在递归调用的参数上进行递归。 例如(这里我使用的是OCaml) 递归: let rec fact n = if n=0 then 1 else n* fact (n-1);; 尾部递归: let fact n = let rec helper (n,m)= if n=0 then m else helper(n-1,n*m) in helper(

所以tailrecursive意味着一个递归函数,它在主体中使用一个递归调用。此外,它是最外层的,这意味着递归调用不在语句内部,而是在递归调用的参数上进行递归。 例如(这里我使用的是OCaml)

递归:

let rec fact n =
if n=0 then 1
else n* fact (n-1);;
尾部递归:

let fact n =
let rec helper (n,m)=
    if n=0 then m
    else helper(n-1,n*m)
in 
helper(n,1);;
我不明白为什么尾巴会比另一个好

还有一些关于OCamel的问题:我们必须担心凹痕吗?因为当我在tryOCamel中尝试时,我们似乎没有

另外,我们可以为OCaml问题创建一个新标签吗?
请帮助

尾部递归不会引起常规递归涉及的堆栈深度问题。由于尾部递归直接将结果返回给父级,因此在进行下一次递归调用时,堆栈帧将被丢弃。这允许更深入(无限)的递归。递归调用中的每个内部步骤基本上都被新调用替换

在您的示例中:

let rec fact n =
    if n=0 then 1
    else n * fact (n-1);;
必须为调用的每次迭代存储
n*事实(n-1)
中的第一个n;因此,当堆叠展开时,可以使用(n*…)


第二个示例将n*当前结果(m)作为参数传递,并且在堆栈“展开”时不需要任何操作,因为最后的n*m计算返回完整的答案。

尾部递归不需要在返回的每一步都对结果进行乘法,只需返回原始被调用方的结果。实际上,只有第一个调用是真正的函数调用,而其他调用是gotos。在函数的结果上重复一个延续的递归需要返回以执行该步骤,如果递归足够深,它通常会破坏堆栈。尾部递归不必使用称为尾部调用消除的技巧来增加堆栈。OCaml没有缩进块。您的屏幕截图显示语法错误,因为
终止表达式,但
let rec funct=
不完整。另外,您似乎在某个地方有一个打字错误
fuct
,而不是
func
。请复制粘贴你的输出,而不是把截图放进去,因为盲人不容易阅读。