根据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]
处失败,而它应该比第一个函数提供更好的性能,因为它使用尾递归。
还有其他因素会影响递归函数吗?
答案 0 :(得分:10)
您的第二个函数不是尾递归,因为loop t acc + h
被解析为(loop t acc) + h
,这使+
成为loop
上的最后一个操作。
将loop t acc + h
更改为loop t (acc + h)
,以使该函数变为尾递归。