Ich weiß, dass dies möglicherweise kein einfacher Ansatz ist, aber ich habe aus funktionalen Sprachen etwas über eine Technik namens "Fix" gelernt . Die fix
Funktion von Haskell ist allgemeiner als der Y-Kombinator bekannt , der einer der bekanntesten Festpunktkombinatoren ist .
Ein Festpunkt ist ein Wert, der von einer Funktion nicht geändert wird : Ein Festpunkt einer Funktion f ist ein beliebiges x, so dass x = f (x). Ein Festpunktkombinator y ist eine Funktion, die für jede Funktion f einen Festpunkt zurückgibt. Da y (f) ein fester Punkt von f ist, haben wir y (f) = f (y (f)).
Im Wesentlichen erstellt der Y-Kombinator eine neue Funktion, die alle Argumente des Originals sowie ein zusätzliches Argument verwendet, das die rekursive Funktion ist. Wie dies funktioniert, ist unter Verwendung der Curry-Notation offensichtlicher. Anstatt Argumente in Klammern ( f(x,y,...)
) zu schreiben, schreiben Sie sie nach der Funktion : f x y ...
. Der Y-Kombinator ist definiert als Y f = f (Y f)
; oder mit einem einzigen Argument für die rekursive Funktion , Y f x = f (Y f) x
.
Da PHP nicht automatisch Curry- Funktionen verwendet, ist es ein bisschen schwierig, die fix
Arbeit zum Laufen zu bringen , aber ich finde es interessant.
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 );
Beachten Sie, dass dies fast das gleiche ist wie die einfachen Verschlusslösungen, die andere veröffentlicht haben, aber die Funktion fix
erstellt den Verschluss für Sie. Festkomma-Kombinatoren sind etwas komplexer als die Verwendung eines Verschlusses, jedoch allgemeiner und haben andere Verwendungszwecke. Während die Verschlussmethode besser für PHP geeignet ist (was keine besonders funktionale Sprache ist), ist das ursprüngliche Problem eher eine Übung als für die Produktion, sodass der Y-Kombinator ein praktikabler Ansatz ist.
global $factorial
?