Programación en Erlang/Iteraciones y recursiones
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.
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).