递归是Erlang的重要组成部分,首先,让我们看看如何通过实现阶乘程序来实现简单的递归。
-module(helloLearnfk). -export([fac/1,start/0]). fac(N) when N == 0 -> 1; fac(N) when N > 0 -> N*fac(N-1). start() -> X=fac(4), io:fwrite("~w",[X]).
关于上述程序,需要注意以下几点:
我们首先定义一个名为fac(N)的函数。
我们能够通过递归调用fac(N)函数。
上面程序的输出是-
24
在本节中,我们将详细了解递归的不同类型及其在Erlang中的用法。
Length递归
通过一个用于确定列表长度的简单示例,可以看到一种更实用的递归方法。列表可以具有多个值,如[1,2,3,4]。
-module(helloLearnfk). -export([len/1,start/0]). len([]) -> 0; len([_|T]) -> 1 + len(T). start() -> X=[1,2,3,4], Y=len(X), io:fwrite("~w",[Y]).
关于上述程序,需要注意以下几点:
如果列表为空,则第一个函数 len([])用于特殊情况。
[H | T] 模式与一个或多个元素的列表匹配,因为长度为1的列表将定义为 [X | []] ,长度为2的列表将定义为 [X | [Y | []]] 。
上面程序的输出将是-
4
Tail尾递归
为了了解尾递归的工作原理,让我们了解上一节中的以下代码如何工作。
len([]) -> 0; len([_|T]) -> 1 + len(T).
让我们看一下尾递归的示例-
-module(helloLearnfk). -export([tail_len/1,tail_len/2,start/0]). tail_len(L) -> tail_len(L,0). tail_len([], Acc) -> Acc; tail_len([_|T], Acc) -> tail_len(T,Acc+1). start() -> X=[1,2,3,4], Y=tail_len(X), io:fwrite("~w",[Y]).
上面程序的输出是-
4
我们来看一个递归示例。这次让我们编写一个函数,该函数将整数作为第一个参数,然后将任何其他术语作为第二个参数。
-module(helloLearnfk). -export([duplicate/2,start/0]). duplicate(0,_) -> []; duplicate(N,Term) when N > 0 -> io:fwrite("~w,~n",[Term]), [Term|duplicate(N-1,Term)]. start() -> duplicate(5,1).
上面程序的输出将是-
1, 1, 1, 1, 1,
List递归
在Erlang中可以使用递归没有任何限制。现在让我们快速看一下如何使用递归来反转列表的元素。
-module(helloLearnfk). -export([tail_reverse/2,start/0]). tail_reverse(L) -> tail_reverse(L,[]). tail_reverse([],Acc) -> Acc; tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]). start() -> X=[1,2,3,4], Y=tail_reverse(X), io:fwrite("~w",[Y]).
上面程序的输出将是-
[4,3,2,1]
参考链接
https://www.learnfk.com/erlang/erlang-recursion.html
标签:Acc,教程,递归,无涯,len,start,tail,fac,Erlang From: https://blog.51cto.com/u_14033984/8659280