Programación en Erlang/Iteraciones y recursiones

De Wikilibros, la colección de libros de texto de contenido libre.

Guard sequences[editar]

Una secuencia de guardia es un conjunto de guardias separados por punto y coma (;). La secuencia de guardia es cierto si al menos uno de los guardias es cierto. GUARD1, ...; GuardK Un guard es un conjunto de expresiones del guard , separadas por comas (,). El guard es cierto si todas las expresiones de la Guardia resultado verdadero. GuardExpr1, ..., GuardExprN Las expresiones del Guard permitido (a veces se llaman pruebas de guard) es un subconjunto del conjunto de las expresiones válidas Erlang, desde la evaluación de una expresión de guard debe ser garantizado de estar libre de efectos secundarios.

Expresiones Validas de los Guards
atom true
Otras constantes (términos y variables ligadas), todos considerados como falsos
Comparacion de terminos
Expresiones aritmeticas y booleanas
Llamadas al BIFs (Built-in functions) especificadas abajo
Tipo de prueba BIFs Otros BIFS permitidos en los guards
is_atom/1 Float)
is_constant/1 float(Term)
is_integer/1 Float)
is_float/1 Float)
is_number/1 Binary)
is_reference/1 element(N, Tuple)
is_port/1 hd(List)
is_pid/1 tl(List)
is_function/1 length(List)
is_tuple/1 self()
is_record/2 The 2nd argument is the record name node()
is_list/1 Ref|Port)
is_binary/1

pequeño ejemplo:

   fact(N) when N>0 ->  % first clause head
       N * fact(N-1);   % first clause body
   fact(0) ->           % second clause head
           1.                    % second clause body

Tail Recursion[editar]

Si la última expresión de una función es una llamada de función, una llamada recursiva de tail se realiza de tal manera que no hay recursos del sistema (como la pila de llamadas) se consumen. Esto significa que un bucle infinito, como un servidor se puede programar de manera que sólo utiliza las llamadas tail recursivas.

fact(N) when N>1 -> fact(N, N-1); fact(N) when N=1; N=0 -> 1.

fact(F,0) -> F; % The variable F is used as an accumulator fact(F,N) -> fact(F*N, N-1).


Ejemplo 1:

Construye un lista, imprime la function, aplicando la function a la lista lists:map(). Retorna un valor.

counter1() -> L = lists:seq(1,10), PrintInt = fun(I) -> io:fwrite("~p ", [I]) end, lists:foreach(PrintInt, L). counter3() -> L = lists:seq(1,10), [ printInt(I) || I <- L].

Ejemplo 2:

Recursión con un acumulador. usar un guard sequence ("cuando N > 10") para especificar el caso base. Se define dos funciones "counter4/0" (zero args) y "counter4/1".

"counter4/1" consiste en dos clausulas separadas por ; counter4() -> counter4(1). counter4(N) when N > 10 -> none; counter4(N) -> printInt(N), counter4(N + 1).

Ejemplo 3: Procesamiento de la lista con un acumulador

counter6() -> %L = [1,1,1,1,1,1,1,1,1,1], L = lists:duplicate(10,1), counter6(L, 0). counter6([], Acc) -> Acc; counter6([H|T], Acc) -> N = H + Acc, printInt(N), counter6(T, N).

Ejemplo 4: Procesamieinto de una matriz con recursividad count_matrix1() -> count_matrix1( 5, 0, 0 ). count_matrix1(Size, Size, Size) -> none; count_matrix1(Size, Size, PtrY) -> io:format("~n"), count_matrix1(Size, 0, PtrY+1); count_matrix1(Size, PtrX, PtrY) -> io:format("(~p,~p) ", [PtrX, PtrY]), count_matrix1(Size, PtrX+1, PtrY).