为什么对于正常递归函数成功执行的输入,尾递归函数失败?

时间:2012-04-11 12:20:15

标签: f# tail-recursion

根据MSDN文档,在编写递归函数时,使用accumulator参数会使函数tail递归,从而节省堆栈空间。 我正在使用MSDN网站上给出的两个示例来计算列表中所有数字的总和 -

首先没有尾递归 -

let rec Sum myList =
    match myList with
    | [] -> 0
    | h::t -> h + Sum t

现在使用尾递归 -

let Sumtail list =
    let rec loop list acc =
        match list with
        | h::t -> loop t acc + h
        | [] -> acc
    loop list 0

并使用输入[1..100000]运行这两个函数。 函数Sum成功计算此列表的总和,但如果我通过[1..1000000],则会给出stackoverflow异常 但是第二个函数Sumtail[1..100000]处失败,而它应该比第一个函数提供更好的性能,因为它使用尾递归。 还有其他因素会影响递归函数吗?

1 个答案:

答案 0 :(得分:10)

您的第二个函数不是尾递归,因为loop t acc + h被解析为(loop t acc) + h,这使+成为loop上的最后一个操作。

loop t acc + h更改为loop t (acc + h),以使该函数变为尾递归。