Ich verstehe den Unterschied zwischen einer Teilfunktionsanwendung und einer Curry-Funktion ( f(X x Y x Z) -> N
vs f(X -> (Y -> (Z -> N)))
), aber ich sehe nicht, welche Konsequenzen dieser Unterschied bei der Entwicklung von Software hat.
Ich verstehe den Unterschied zwischen einer Teilfunktionsanwendung und einer Curry-Funktion ( f(X x Y x Z) -> N
vs f(X -> (Y -> (Z -> N)))
), aber ich sehe nicht, welche Konsequenzen dieser Unterschied bei der Entwicklung von Software hat.
Ursprünglich sollte das Currying eher die Analyse vereinfachen als eine praktische Programmiertechnik. In der Lambda-Rechnung sind alle Funktionen unär. Currying wird häufig auf Sprachebene aus einem ähnlichen Grund verwendet: Vereinfachung des Rechenmodells.
Eine Teilanwendung wird verwendet, wenn eine benannte, nützliche Funktion in Bezug auf eine andere, allgemeinere Funktion implementiert werden kann, indem einfach ein Argument festgelegt wird.
Sie bleiben unterschiedliche Formen, die verschiedene Teile der Berechnung umfassen. Erwägen:
x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)
Beachten Sie, dass eine Curry-Funktion keine an Argumente gebundenen Werte hat und die Argumente in einer bestimmten Reihenfolge akzeptiert. Sobald Sie eine Funktion curry, curry Sie das Ergebnis nicht und ändern nicht die Reihenfolge, in der die Funktion Argumente akzeptiert (obwohl Sie dies entschlüsseln und curry könnten). Im Gegensatz dazu hat eine Teilfunktion Werte, die an Argumente gebunden sind, und kann weiter teilweise auf jedes verbleibende Argument angewendet werden.
Das Anwenden einer Curry-Funktion steht kurz vor der teilweisen Anwendung (Sie curry schließlich keine Funktion und belassen sie dabei; irgendwann werden Sie sie anwenden). Hier beginnen sich die Verwendungen zu überschneiden. Wenn Sie dies tun, ist das Currying nur der erste von zwei Schritten zur teilweisen Anwendung.
Ich glaube, dass Ihre Frage wie folgt umformuliert werden kann: Warum haben Sprachen Currying?
Es ist meistens eine Frage der Bequemlichkeit:
In Ocaml können Sie codieren
let sum3 x y z = x + y + z;;
let foo xx yy ll = List.map (sum3 xx yy) ll;;
In Schema müssen Sie explizit eine anonyme Funktion erstellen
(define (sum3 x y z) (+ x y z))
(define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))
Sprachen mit Teilanwendungen und Currying müssen praktisch optimiert werden, um zu vermeiden, dass überall Teilschließungen erstellt werden. Sie möchten nicht, dass die Implementierung immer so angewendet wird, sum3
als ob sie definiert wäre als
let sum3 x =
fun y ->
(fun z -> x + y + z)
das heißt, 2 Zwischenverschlüsse beim Rechnen zuzuweisen sum3 1 2 3
(verstanden und analysiert als ((sum3 1) 2) 3
...). Sie möchten, dass die Summe sofort berechnet wird.