Sé que esto podría no ser un enfoque simple, pero aprendí acerca de una técnica llamada "arreglo" de los lenguajes funcionales. La fix
función de Haskell se conoce más generalmente como el combinador Y , que es uno de los combinadores de punto fijo más conocidos .
Un punto fijo es un valor que no se modifica por una función: un punto fijo de una función f es cualquier x tal que x = f (x). Un combinador de punto fijo y es una función que devuelve un punto fijo para cualquier función f. Como y (f) es un punto fijo de f, tenemos y (f) = f (y (f)).
Esencialmente, el combinador Y crea una nueva función que toma todos los argumentos del original, más un argumento adicional que es la función recursiva. Cómo funciona esto es más obvio usando la notación al curry. En lugar de escribir argumentos entre paréntesis ( f(x,y,...)
), escribirlas después de la función: f x y ...
. El combinador Y se define como Y f = f (Y f)
; o, con un solo argumento para la función recursed, Y f x = f (Y f) x
.
Dado que PHP no curry automáticamente las funciones, es un poco complicado hacer el fix
trabajo, pero creo que es interesante.
function fix( $func )
{
return function() use ( $func )
{
$args = func_get_args();
array_unshift( $args, fix($func) );
return call_user_func_array( $func, $args );
};
}
$factorial = function( $func, $n ) {
if ( $n == 1 ) return 1;
return $func( $n - 1 ) * $n;
};
$factorial = fix( $factorial );
print $factorial( 5 );
Tenga en cuenta que esto es casi lo mismo que las soluciones de cierre simples que otros han publicado, pero la función fix
crea el cierre por usted. Los combinadores de punto fijo son ligeramente más complejos que usar un cierre, pero son más generales y tienen otros usos. Si bien el método de cierre es más adecuado para PHP (que no es un lenguaje terriblemente funcional), el problema original es más un ejercicio que para la producción, por lo que el combinador Y es un enfoque viable.
global $factorial
?