829 Stimmen

Was ist "Currying"?

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!)

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 y uncurry 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 als add (x, y)=x+y (ohne Eile)

5voto

Mario Punkte 6334

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.

5voto

Prashant Andani Punkte 99

Hier ist ein Beispiel für die generische und die kürzeste Version für das Currying von Funktionen mit n Parametern.

const add = a => b => b ? add(a + b) : a; 

const add = a => b => b ? add(a + b) : a; 
console.log(add(1)(2)(3)(4)());

4voto

Marcus Thornton Punkte 5451

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.

3voto

user3804449 Punkte 69

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)

3voto

James Black Punkte 41034

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X