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)

35voto

J D Punkte 47190

Eine curried-Funktion ist eine Funktion mit mehreren Argumenten, die so umgeschrieben wird, dass sie das erste Argument akzeptiert und eine Funktion zurückgibt, die das zweite Argument akzeptiert usw. Auf diese Weise können bei Funktionen mit mehreren Argumenten einige ihrer ursprünglichen Argumente teilweise übernommen werden.

7 Stimmen

"Dies ermöglicht es Funktionen mit mehreren Argumenten, dass einige ihrer ursprünglichen Argumente teilweise angewendet werden." - Warum ist das von Vorteil?

7 Stimmen

@acarlon Funktionen werden oft wiederholt mit einem oder mehreren gleichen Argumenten aufgerufen. Zum Beispiel, wenn Sie map eine Funktion f über eine Liste von Listen xss können Sie tun map (map f) xss .

1 Stimmen

Vielen Dank, das macht Sinn. Ich habe ein bisschen mehr gelesen, und es hat sich alles gefügt.

15voto

Yilmaz Punkte 12859

Currying bedeutet die Umwandlung einer Funktion der Arität N in N Funktionen der Arität 1. Die arity der Funktion ist die Anzahl der Argumente, die sie benötigt.

Hier ist die formale Definition:

 curry(f) :: (a,b,c) -> f(a) -> f(b)-> f(c)

Hier ist ein Beispiel aus der Praxis, das Sinn macht:

Sie gehen zum Geldautomaten, um Geld zu holen. Sie ziehen Ihre Karte durch, geben Ihre PIN-Nummer ein, treffen Ihre Auswahl und drücken dann die Eingabetaste, um den "Betrag" neben der Anforderung zu übermitteln.

hier ist die normale Funktion zum Abheben von Geld.

const withdraw=(cardInfo,pinNumber,request){
    // process it
       return request.amount
}

In dieser Implementierung erwartet die Funktion, dass wir alle Argumente auf einmal eingeben. Wir würden die Karte durchziehen, die PIN eingeben und die Anfrage stellen, dann würde die Funktion ausgeführt. Wenn einer dieser Schritte ein Problem hätte, würden Sie es herausfinden, nachdem Sie alle Argumente eingegeben haben. Mit Curried Function würden wir reine und einfache Funktionen mit höherer Arität erstellen. Reine Funktionen helfen uns bei der Fehlersuche in unserem Code.

Dies ist Atm mit Curried-Funktion:

const withdraw=(cardInfo)=>(pinNumber)=>(request)=>request.amount

Der Geldautomat nimmt die Karte als Eingabe und gibt eine Funktion zurück, die die PIN-Nummer erwartet, und diese Funktion gibt eine Funktion zurück, die das Anforderungsobjekt annimmt, und nach dem erfolgreichen Prozess erhalten Sie den angeforderten Betrag. Bei jedem Schritt, bei dem ein Fehler auftritt, können Sie leicht vorhersagen, was schief gelaufen ist. Angenommen, Sie geben die Karte ein und erhalten eine Fehlermeldung, dann wissen Sie, dass es entweder mit der Karte oder dem Gerät zusammenhängt, aber nicht mit der Pin-Nummer. Oder wenn Sie die PIN eingegeben haben und sie nicht akzeptiert wird, wissen Sie, dass Sie die PIN-Nummer falsch eingegeben haben. Sie können den Fehler leicht beheben.

Außerdem ist jede Funktion hier wiederverwendbar, so dass Sie dieselben Funktionen in verschiedenen Teilen Ihres Projekts verwenden können.

9voto

MidhunKrishna Punkte 611

Currying ist das Übersetzen einer Funktion von callable als f(a, b, c) in abrufbar als f(a)(b)(c) .

Ansonsten wird eine Funktion, die mehrere Argumente benötigt, in eine Reihe von Funktionen aufgeteilt, die einen Teil der Argumente übernehmen.

Wörtlich genommen ist Currying eine Umwandlung von Funktionen: von einer Art des Aufrufs in eine andere. In JavaScript machen wir normalerweise einen Wrapper, um die ursprüngliche Funktion zu erhalten.

Currying ruft keine Funktion auf. Es wandelt sie nur um.

Lassen Sie uns eine Curry-Funktion erstellen, die Currys für Funktionen mit zwei Argumenten durchführt. Mit anderen Worten, curry(f) für Zwei-Argumente f(a, b) übersetzt es in f(a)(b)

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// usage
function sum(a, b) {
  return a + b;
}

let carriedSum = curry(sum);

alert( carriedSum(1)(2) ); // 3

Wie Sie sehen können, besteht die Implementierung aus einer Reihe von Wrappern.

  • Das Ergebnis von curry(func) ist ein Wrapper function(a) .
  • Wenn sie wie folgt aufgerufen wird sum(1) wird das Argument in der lexikalischen Umgebung gespeichert, und es wird ein neuer Wrapper zurückgegeben function(b) .
  • Dann sum(1)(2) ruft schließlich function(b) die 2 liefert, und übergibt den Aufruf an die ursprüngliche Multi-Argument-Summe.

7voto

Anon Punkte 11126

Hier ist ein kleines Beispiel in Python:

>>> from functools import partial as curry

>>> # Original function taking three parameters:
>>> def display_quote(who, subject, quote):
        print who, 'said regarding', subject + ':'
        print '"' + quote + '"'

>>> display_quote("hoohoo", "functional languages",
           "I like Erlang, not sure yet about Haskell.")
hoohoo said regarding functional languages:
"I like Erlang, not sure yet about Haskell."

>>> # Let's curry the function to get another that always quotes Alex...
>>> am_quote = curry(display_quote, "Alex Martelli")

>>> am_quote("currying", "As usual, wikipedia has a nice summary...")
Alex Martelli said regarding currying:
"As usual, wikipedia has a nice summary..."

(Ich verwende nur die Verkettung mittels +, um Ablenkung für Nicht-Python-Programmierer zu vermeiden).

Editieren um hinzuzufügen:

Siehe http://docs.python.org/library/functools.html?highlight=partial#functools.partial , die auch den Unterschied zwischen Teilobjekten und Funktionen in der Art und Weise zeigt, wie Python dies implementiert.

0 Stimmen

Ich verstehe das nicht - Sie machen das: >>> am_quote = curry(display_quote, "Alex Martelli"), aber dann machst du das nächste: >>> am_quote("currying", "As usual, wikipedia has a nice summary...") Sie haben also eine Funktion mit zwei Argumenten. Es scheint, dass Currying drei verschiedene Funktionen liefern sollte, die man zusammensetzen kann?

1 Stimmen

Ich verwende partiell, um nur einen Parameter mitzuteilen und eine Funktion mit zwei Argumenten zu erzeugen. Wenn Sie wollten, könnten Sie auch am_quote verwenden, um eine Funktion zu erstellen, die nur Alex zu einem bestimmten Thema zitiert. Der mathematische Hintergrund mag sich darauf konzentrieren, Funktionen mit nur einem Parameter zu erhalten - aber ich glaube, dass das Festlegen einer beliebigen Anzahl von Parametern auf diese Weise allgemein (wenn auch aus mathematischer Sicht ungenau) als Curry bezeichnet wird.

0 Stimmen

(btw - das '>>>' ist die Eingabeaufforderung im interaktiven Python-Interpreter, nicht Teil des Codes).

6voto

Currying ist eine der übergeordneten Funktionen von Java Script.

Currying ist eine Funktion mit vielen Argumenten, die so umgeschrieben wird, dass sie das erste Argument nimmt und eine Funktion zurückgibt, die wiederum die übrigen Argumente verwendet und den Wert zurückgibt.

Verwirrt?

Sehen wir uns ein Beispiel an,

function add(a,b)
    {
        return a+b;
    }
add(5,6);

Dies ist vergleichbar mit der folgenden Currying-Funktion,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }
var curryAdd = add(5);
curryAdd(6);

Was bedeutet dieser Code also?

Lesen Sie nun die Definition noch einmal,

Currying ist eine Funktion mit vielen Argumenten, die so umgeschrieben wird, dass sie das erste Argument übernimmt und eine Funktion zurückgibt, die wiederum die übrigen Argumente verwendet und den Wert zurückgibt.

Immer noch verwirrt? Lassen Sie mich das erklären!

Wenn Sie diese Funktion aufrufen,

var curryAdd = add(5);

Sie erhalten dann eine Funktion wie diese,

curryAdd=function(y){return 5+y;}

Dies wird also als Funktionen höherer Ordnung bezeichnet. Das heißt, der Aufruf einer Funktion, die wiederum eine andere Funktion zurückgibt, ist eine genaue Definition für eine Funktion höherer Ordnung. Dies ist der größte Vorteil für die Legende Java Script. Kommen wir also zurück zum Currying,

Mit dieser Zeile wird das zweite Argument an die Funktion curryAdd übergeben.

curryAdd(6);

was wiederum zur Folge hat,

curryAdd=function(6){return 5+6;}
// Which results in 11

Ich hoffe, Sie verstehen die Verwendung von Curry hier. Kommen wir also zu den Vorteilen,

Warum Currying?

Es nutzt die Wiederverwendbarkeit von Code. Weniger Code, weniger Fehler. Sie fragen sich vielleicht, wie es weniger Code ist?

Ich kann es mit den neuen ECMA-Skript 6-Feature-Pfeilfunktionen beweisen.

Ja! ECMA 6 bietet uns die wunderbare Funktion der Pfeilfunktionen,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }

Mit Hilfe der Pfeilfunktion können wir die obige Funktion wie folgt schreiben,

x=>y=>x+y

Cool, oder?

Also, weniger Code und weniger Bugs!

Mit Hilfe dieser Funktionen höherer Ordnung kann man leicht einen fehlerfreien Code entwickeln.

Ich fordere Sie heraus!

Ich hoffe, Sie haben verstanden, was Curry ist. Bitte zögern Sie nicht, hier zu kommentieren, wenn Sie weitere Erklärungen benötigen.

Danke, einen schönen Tag noch!

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