Ihre $comp
ist curried und natürlich Sie entdeckt PHP native array_reduce
erwartet, dass die Funktion mehrere Parameter akzeptiert - eine schnelle Anwendung von uncurry
dauert einige Ihrer Schmerzen entfernt, aber Sie müssen weiterlesen, wenn Sie sehen möchten, wie dies insgesamt verbessert werden kann ...
in bescheidenen Meinung nach PHP ...
Mit uncurry funktioniert der Trick, aber Sie werden wahrscheinlich Ihr Programm am Ende nicht zu mögen, wenn alle Funktionen als $
-named Variablen definiert sind - Ich sehe viele kleine Probleme mit diesem Stil.
PHP hat einen callable „Typ“, die Dinge ein wenig mehr PHP-ish macht - benutzerdefinierte Funktionen (einschließlich Funktionen höherer Ordnung) sollten mit call_user_func und call_user_func_array
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 mit Ihrem heißen compn
variadische Schnittstelle arbeitet als
erwartet
function compn (...$fs) {
return fold ('comp', 'identity') ($fs);
}
function inc ($x) {
return $x + 1;
}
echo compn ('inc', 'inc', 'inc') (0); // 3
Aber es funktioniert mit anonymen Funktionen zu
Funktionscode, modulares Programm
Mit Ihrer Funktionen deklariert function
Syntax verwenden, können Sie sie in andere Bereiche des Programms
// 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 Sie don import Wenn Sie eine Ihrer Funktionen verwenden möchten, müssen Sie use
-Blöcken mit Code
// before
$compn = function (...$fs) use ($fold, $comp, $id) {
return $fold($comp, $id) ($fs);
};
// after
function compn (...$fs) {
return fold ('comp', 'id') ($fs);
}
Wenn es zu debuggen kommt, zweifellos die namens Funktionen bieten hilfreiche Stack-Trace-Nachrichten als auch
relevant, aber unwichtig
PHP hat andere Gründe für das Hinzufügen der aufrufbare Art, aber diejenigen, die ich sicher bin, die nicht betreffen Sie wie sie sind OOP-bezogene - zB
Klasse Methode ruft
// MyClass::myFunc (1);
call_user_func (['MyClass', 'myFunc'], 1);
Objektmethode
// $me->myfunc (1);
call_user_func ([$me, 'myfunc'], 1);
Funktionale Programmierung ruft nicht gut in PHP nicht das Gefühl, als es nicht gut fühlen in JavaScript entweder. Diese Sprachen waren einfach nicht für FP gedacht. Es kann getan werden, wie Sie bereits herausgefunden haben, aber es ist eine Menge Code, der eine Menge Tricks erfordert, um es in die gewünschte Richtung zu schieben. Es ist schön wie eine Übung, aber ich würde es nicht in die Produktion verwenden. Zumindest in PHP ist eine äquivalente OOP-Lösung (wahrscheinlich mit [fluent interface] (https://martinfowler.com/bliki/FluentInterface.html) besser lesbar und bietet, mehr oder weniger, die nette API, die Sie wünschen. – axiac