Ich möchte eine Kompositionsfunktion für n-Funktionen aus Reduzieren / Falten ableiten, aber es funktioniert nicht wie erwartet:
$id = function ($x) {
return $x;
};
$comp = function ($f) {
return function ($g) use ($f) {
return function ($x) use ($f, $g) {
return $f($g($x));
};
};
};
$fold = function ($f, $acc) {
return function ($xs) use ($f, &$acc) {
return array_reduce($xs, $f, $acc);
};
};
$compn = function($fs) {/* apply $fold here */};
$inc = function ($n) {
return $n + 1;
};
$fold($comp, $id) ([$inc, $inc, $inc]) (0); // yields a closure instead of 3
Ich habe die gleiche Funktion in Javascript implementiert und es funktioniert. Ich benutze PHP 7.0.8 cli. Ich weiß nicht viel über PHP, daher übersehen ich wahrscheinlich etwas.
Ihr $comp
ist Curry , und natürlich haben Sie festgestellt, dass PHPs native array_reduce
erwartet, dass die Funktion mehrere Parameter akzeptiert - eine schnelle Anwendung von uncurry
nimmt Ihnen einige Schmerzen, aber Sie müssen weiterlesen, wenn Sie sehen möchten, wie dies insgesamt verbessert werden kann. ..
nach PHPs bescheidener Meinung ...
Die Verwendung von uncurry reicht aus, aber Sie werden Ihr Programm wahrscheinlich nicht mögen, wenn alle Funktionen als $
benannte Variablen definiert sind. Ich sehe viele kleine Probleme bei der Verwendung dieses Stils.
PHP hat einen aufrufbaren "Typ", der die Dinge ein wenig PHP-artiger macht - benutzerdefinierte Funktionen (einschließlich Funktionen höherer Ordnung) sollten mit call_user_func und call_user_func_array aufgerufen werden
namespace my\module;
function identity ($x) {
return $x;
}
function comp ($f) {
return function ($g) use ($f) {
return function ($x) use ($f, $g) {
return call_user_func ($f, call_user_func ($g, $x));
};
};
}
function uncurry ($f) {
return function ($x, $y) use ($f) {
return call_user_func (call_user_func ($f, $x), $y);
};
}
function fold ($f, $acc) {
return function ($xs) use ($f, $acc) {
return array_reduce ($xs, uncurry ($f), $acc);
};
}
Jetzt compn
funktioniert Ihre mit variadic Schnittstelle wie erwartet
function compn (...$fs) {
return fold ('comp', 'identity') ($fs);
}
function inc ($x) {
return $x + 1;
}
echo compn ('inc', 'inc', 'inc') (0); // 3
Es funktioniert aber auch mit anonymen Funktionen
$double = function ($x) { return $x + $x; };
echo compn ($double, $double, 'inc') (2); // 12
Funktionscode, modulares Programm
Wenn Ihre Funktionen mithilfe der function
Syntax deklariert wurden , können Sie sie in andere Bereiche Ihres Programms importieren
// single import
use function my\module\fold;
// aliased import
use function my\module\fold as myfold;
// multiple imports
use function my\module\{identity, comp, compn, fold};
Und jetzt müssen Sie use
Ihren Code nicht jedes Mal mit -blocks verunreinigen, wenn Sie eine Ihrer Funktionen verwenden möchten
// before
$compn = function (...$fs) use ($fold, $comp, $id) {
return $fold($comp, $id) ($fs);
};
// after
function compn (...$fs) {
return fold ('comp', 'id') ($fs);
}
Wenn es um das Debuggen geht, bieten die genannten Funktionen zweifellos auch hilfreichere Stack-Trace-Nachrichten
relevant, aber unwichtig
PHP hat andere Gründe für das Hinzufügen des aufrufbaren Typs, aber diejenigen, die Sie sicher nicht betreffen, da sie OOP-bezogen sind - z.
Klassenmethodenaufrufe
// MyClass::myFunc (1);
call_user_func (['MyClass', 'myFunc'], 1);
Objektmethodenaufrufe
// $me->myfunc (1);
call_user_func ([$me, 'myfunc'], 1);
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen