English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
La recursión es una parte importante de Erlang. Primero, veamos cómo se puede implementar una recursión simple mediante un programa factorial.
-module(helloworld). -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]).
Sobre el programa anterior, hay algunos puntos que需要注意:
Primero, definimos una función llamada fac(N).
Podemos definir una función recursiva mediante la llamada recursiva fac(N).
La salida del programa anterior es:
24
En esta sección, profundizaremos en los diferentes tipos de recursión y su uso en Erlang.
Un método más práctico de recursión se puede ver en un simple ejemplo para determinar la longitud de una lista. Una lista puede tener varios valores, como [1,2,3,4]. Vamos a usar la recursión para ver cómo obtener la longitud de una lista.
-module(helloworld). -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]).
Sobre el programa anterior, hay algunos puntos que需要注意:
Si la lista está vacía, se utiliza la función len([]) para el caso especial de la condición.
Se utiliza el patrón [H|T] para coincidir con una lista de un o más elementos, como una lista de longitud1La lista se definirá como [X|[]], y tendrá una longitud de 2 La lista se definirá como [X|[Y|[]]] .
Notar que el segundo elemento es la lista en sí. Esto significa que solo necesitamos contar el primero, y la función puede llamarse a sí misma en el segundo elemento. La longitud de cada valor dado en la lista se define como 1 .
La salida del programa anterior será
4
Para entender cómo funciona la recursión terminal, veamos cómo funciona el siguiente código en la sección anterior.
Sintaxis
len([]) -> 0; len([_|T]) -> 1 + len(T).
1 + La respuesta de len (Rest) necesita encontrar la respuesta de len (Rest). Luego, la función len (Rest) en sí misma necesita encontrar el resultado de otra llamada a la función. La parte agregada se acumulará hasta que se encuentre la última, luego se calculará el resultado final.
La recursión terminal está diseñada para eliminar estas operaciones de acumulación al reducirlas en el momento de la operación.
Para lograr esto, necesitamos mantener una variable temporal adicional como parámetro en la función. La variable temporal mencionada anteriormente a veces se llama acumulador y se utiliza como lugar de almacenamiento de resultados de cálculo para limitar el crecimiento de las llamadas.
Veamos un ejemplo de recursión terminal
-module(helloworld). -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]).
La salida del programa anterior es
4
Veamos un ejemplo de recursión. Esta vez, escribiremos una función que tome un entero como primer parámetro y cualquier otro elemento como segundo parámetro. Luego, creará una lista de réplicas del término especificado por el entero.
Veamos un ejemplo de esto-
-module(helloworld). -export([duplicate/2,start/0]). duplicate(0,_) -> []; duplicate(N,Term) cuando N > 0 -> io:fwrite("~w,~n",[Term]), [Term|duplicate(N-1,Term)]. start() -> duplicate(5,1.
La salida del programa anterior será-
1, 1, 1, 1, 1,
En Erlang se puede usar recursión sin limitaciones. Ahora veamos rápidamente cómo se puede usar recursión para invertir los elementos de una lista. Se puede completar esta operación con el siguiente programa.
-module(helloworld). -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]).
La salida del programa anterior será-
[4,3,2,1]
Sobre el programa anterior, hay algunos puntos que需要注意:
Volvemos a usar el concepto de variable temporal para almacenar cada elemento de la lista en una variable llamada Acc.
Luego llamamos recursivamente a tail_reverse, pero esta vez, nos aseguramos de que el último elemento se coloque primero en la nueva lista.
Luego llamamos recursivamente a tail_reverse para cada elemento de la lista.