Ich habe in mehreren Artikeln und Blogs Hinweise auf Curried-Funktionen gesehen, aber ich kann keine gute Erklärung finden (oder zumindest eine, die Sinn macht!)
Antworten
Zu viele Anzeigen?Wenn Sie verstehen partial
haben Sie die Hälfte geschafft. Die Idee von partial
ist es, einer Funktion Argumente voranzustellen und eine neue Funktion zurückzugeben, die nur die verbleibenden Argumente benötigt. Wenn diese neue Funktion aufgerufen wird, enthält sie die vorgeladenen Argumente zusammen mit allen Argumenten, die ihr zugeführt wurden.
In Clojure +
eine Funktion ist, sondern um die Dinge klar und deutlich zu machen:
(defn add [a b] (+ a b))
Sie wissen vielleicht, dass die inc
Funktion addiert einfach 1 zu der ihr übergebenen Zahl.
(inc 7) # => 8
Bauen wir es selbst mit partial
:
(def inc (partial add 1))
Hier geben wir eine andere Funktion zurück, bei der 1 in das erste Argument von add
. Als add
benötigt zwei Argumente die neue inc
Funktion will nur die b
Argument -- nicht 2 Argumente wie zuvor, da 1 bereits vorhanden ist teilweise angewendet. So partial
ist ein Werkzeug, mit dem man neue Funktionen mit vorgegebenen Werten erstellen kann. Aus diesem Grund sind in einer funktionalen Sprache Funktionen oft in der Reihenfolge der Argumente angeordnet, von allgemein bis spezifisch. Dies erleichtert die Wiederverwendung solcher Funktionen, aus denen andere Funktionen konstruiert werden können.
Stellen Sie sich nun vor, die Sprache wäre klug genug, um von sich aus zu verstehen, dass add
wollte zwei Argumente. Was wäre, wenn die Funktion, wenn wir ihr ein Argument übergeben, das Argument, das wir ihr in unserem Namen übergeben haben, nur teilweise anwendet, weil wir wissen, dass wir das andere Argument wahrscheinlich später angeben wollen? Wir könnten dann definieren inc
ohne ausdrückliche Verwendung von partial
.
(def inc (add 1)) #partial is implied
So verhalten sich einige Sprachen. Es ist besonders nützlich, wenn man Funktionen zu größeren Transformationen zusammensetzen möchte. Dies würde zu Transducern führen.
Curry kann Ihren Code vereinfachen. Dies ist einer der Hauptgründe für die Verwendung dieses Verfahrens. Currying ist ein Prozess der Umwandlung einer Funktion, die n Argumente akzeptiert, in n Funktionen, die nur ein Argument akzeptieren.
Das Prinzip besteht darin, die Argumente der übergebenen Funktion unter Verwendung der Eigenschaft closure (Schließung) zu übergeben, um sie in einer anderen Funktion zu speichern und als Rückgabewert zu behandeln, und diese Funktionen bilden eine Kette, und die letzten Argumente werden übergeben, um die Operation abzuschließen.
Dies hat den Vorteil, dass die Verarbeitung von Parametern vereinfacht werden kann, indem jeweils nur ein Parameter behandelt wird, was auch die Flexibilität und Lesbarkeit des Programms verbessern kann. Dadurch wird das Programm auch überschaubarer. Auch die Aufteilung des Codes in kleinere Teile würde die Wiederverwendung erleichtern.
Zum Beispiel:
function curryMinus(x)
{
return function(y)
{
return x - y;
}
}
var minus5 = curryMinus(1);
minus5(3);
minus5(5);
Ich kann auch...
var minus7 = curryMinus(7);
minus7(3);
minus7(5);
Dies ist sehr gut geeignet, um komplexen Code übersichtlich zu gestalten und unsynchronisierte Methoden usw. zu behandeln.
Wie alle anderen Antworten hilft Currying bei der Erstellung von teilweise angewandten Funktionen. Javascript bietet keine native Unterstützung für automatisches Currying. Daher sind die oben genannten Beispiele in der praktischen Kodierung möglicherweise nicht hilfreich. Es gibt einige exzellente Beispiele in Livescript (das im Wesentlichen zu js kompiliert) http://livescript.net/
times = (x, y) --> x * y
times 2, 3 #=> 6 (normal use works as expected)
double = times 2
double 5 #=> 10
Im obigen Beispiel, wenn Sie weniger Argumente angegeben haben, generiert Livescript eine neue Curried-Funktion für Sie (double)
Ich fand diesen Artikel und den Artikel, auf den er verweist, sehr nützlich, um das Currying besser zu verstehen: http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx
Wie die anderen bereits erwähnt haben, ist es nur eine Möglichkeit, eine Funktion mit einem Parameter zu haben.
Dies ist insofern nützlich, als Sie nicht davon ausgehen müssen, wie viele Parameter übergeben werden, so dass Sie keine Funktionen mit 2 Parametern, 3 Parametern und 4 Parametern benötigen.
13 Stimmen
[Gemäß der Definition einer kartesischen geschlossenen Kategorie gibt es eine fest Familie von Adjunktionen (natürlich parametrisiert durch A) zwischen X -> X x A und X -> X ^ A. Die Isomorphismen hom(X x A, Y) <-> hom(X, Y^A) sind die
curry
yuncurry
Funktionen von Haskell. Wichtig ist hier, dass diese Isomorphismen von vornherein festgelegt und somit in die Sprache "eingebaut" sind.3 Stimmen
Es gibt ein schönes Tutorial hier für currying in haskell learnyouahaskell.com/higher-order-functions#curried-functions Kurzkommentare sind, dass
add x y = x+y
(curried) ist anders alsadd (x, y)=x+y
(ohne Eile)