尾递归
诸如OCaml之类的功能语言在很大程度上依赖于递归函数 。但是,此类函数可能会导致内存过度消耗,或者在处理大型数据集时会导致堆栈溢出 。
在这种情况下,尾递归是优化的重要来源。它允许程序在递归调用是函数的最后一个时删除调用者上下文。
求和函数
下面是一个非尾递归函数,用于计算整数列表的总和。
let rec sum = function
| [] -> 0
| h::t -> h + (sum t)
该函数执行的最后一个操作是添加。因此,该函数不是尾递归的。
下面是相同函数的尾递归版本。
let sum l =
let rec aux acc = function
| [] -> acc
| h::t -> aux (acc+h) t
in
aux 0 l
这里, aux函数是尾递归的:它执行的最后一个操作是调用自身。因此,后一版本的sum可以与任何长度的列表一起使用。