Erlang 中的递归

今天看了看Erlang编程指南,发现其中的递归还是挺有特色的,递归式函数式编程语言的一大特色了。

递归

比如一个求平均数的例子:

1 average(List) -> sum(List) / len(List).
2 
3 sum([]) -> 0;
4 sum([Head | Tail]) -> Head + sum(Tail). 5 len([]) -> 0;
6 len([_ | Tail) -> 1 + len(Tail).

先看sum函数,sum([])->0. 如果列表是空的,那么元素总和是零

sum([Head | Tail]) -> Head + sum(Tail). 如果至少包含一个元素,那么把它分解成头部和尾部,总和就是头部与尾部的和

len函数也同样,由于len只关心个数所以使用了"_",表示头部的值是无关紧要的

 

筛选出列表中所有的偶数:

1 even([]) -> [];
2 even([Head | Tail]) when Head rem 2 == 0 -> [Head | even(Tail)];
3 even([_ | Tail]) -> even(Tail).

这里第二个even使用了保护元(guard)来提供执行函数的前提条件。

 

判断列表中是否有指定元素:

1 member(_, []) -> false;
2 member(H, [H | _]) -> true;
3 member(H, [_ | T]) -> member(H, T).

 

尾递归

尾递归就是调用者在函数的最后调用自己,即不需要保存调用者的堆栈信息,相较于普通递归,更省内存,效率更高。

sum的尾递归版本:

1 sum_acc([], Sum) -> Sum;
2 sum_acc([Head | Tail]), Sum) -> sum_acc(Tail, Head + Sum).

如下调用:

sum(List) -> sum_acc(List, 0).

 

posted @ 2013-01-07 16:21  Excelight  Views(610)  Comments(0)    收藏  举报