Ist es möglich, eine rekursive und anonyme PHP-Funktion zu haben? Dies ist mein Versuch, es zum Laufen zu bringen, aber es wird der Funktionsname nicht übergeben.
$factorial = function( $n ) use ( $factorial ) {
if( $n <= 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
Mir ist auch bewusst, dass dies ein schlechter Weg ist, Fakultät zu implementieren, es ist nur ein Beispiel.
global $factorial
?print $factorial( 0);
Antworten:
Damit es funktioniert, müssen Sie $ factorial als Referenz übergeben
quelle
&
ist von Wert. Alles mit&
ist durch Bezugnahme. "Objekte" sind in PHP5 keine Werte und können nicht zugewiesen oder übergeben werden. Sie haben es mit einer Variablen zu tun, deren Wert eine Objektreferenz ist. Wie alle Variablen kann es nach Wert oder Referenz erfasst werden, je nachdem, ob es eine gibt&
.$factorial
wird vor dem Aufruf der Funktion geändert und kann zu seltsamem Verhalten führen.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 alsY 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.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.quelle
call_user_func_array()
Weihnachten so langsam ist.call_user_func_array
.array_unshift( $args, fix($func) );
? Args ist bereits mit den Parametern beladen, und die eigentliche Rekursion erfolgt durch call_user_func_array (). Was macht diese Zeile also?Obwohl es nicht für den praktischen Gebrauch gedacht ist, bietet die C-Level-Erweiterung mpyw-junks / phpext-callee eine anonyme Rekursion ohne Zuweisung von Variablen .
quelle
In neueren Versionen von PHP können Sie dies tun:
Dies kann möglicherweise zu seltsamem Verhalten führen.
quelle
Sie können Y Combinator in PHP 7.1+ wie folgt verwenden:
Spielen Sie damit: https://3v4l.org/7AUn2
Quellcodes von: https://github.com/whitephp/the-little-phper/blob/master/src/chapter_9.php
quelle
Mit einer anonymen Klasse (PHP 7+), ohne eine Variable zu definieren:
quelle