2016-05-05 13 views
2

Ich versuche, die Ursache und Wirkung Logiken hinter „Currying“ und zu folgenden Ergebnissen kommt, um herauszufinden:Warum Haskell ein Argument nimmt

kann
  1. Mehrere Argumente Funktion entweder als Tupel ausgedrückt werden (Kombination mehrerer Argumente mit verschiedenen Typen als ein Argument) und Liste (mehrere Argumente mit demselben Typ wie ein Argument kombinieren). So können alle Funktionen als einzelne Argumentfunktion ausgedrückt werden.
  2. Also in Haskell, Funktion nimmt nur ein Argument.Wie können wir multiple-Argumente Funktion implementieren.
  3. Verwenden von Curry. Curry ist eine Möglichkeit, mehrere Argumentfunktionen zu implementieren.

Ich denke, die obige Logik 1 -> 2 -> 3 ist verwirrend zu beantworten "warum mit Currying". Für die Aussage 3 kann man auch mehrere Tupel oder Listen als einzelnes Argument zur Implementierung mehrerer Argumente kombinieren.

Es scheint Aussage 1 ist nicht richtig Grund für Aussage 2. Was bin ich sicher, ist 2-> 3 ist richtig Argumentation, aber was ist der Grund hinter 2? Warum hat Haskell als funktionale Sprache nur ein Argument?

Die meisten Bücher nehmen Aussage 2 als eine akzeptierte Tatsache. Kennt jemand den Grund hinter 2? Oder kennt jemand die richtige Logik hinter "warum currying"?

+0

Sie fragen: "Warum Curry verwenden?", Was bedeutet, dass irgendwann jemand dachte: "Lassen Sie uns currying verwenden, um ein Sprachdesignproblem zu lösen, das wir haben." Aber so ist es nicht wirklich passiert. Jemand dachte: "Lasst uns eine Sprache schaffen, die einfach, elegant, ausdrucksstark, bequem, sicher und flexibel ist." Die Lösungen für diese Probleme sind die Verwendung eines Lambda-Kalküls mit induktiven Typen, ein nettes Typsystem und eine etwas ungewöhnliche Reduktionsstrategie. "Currying" ist keine Lösung für eines dieser Probleme, sondern eher ein zufälliges Werkzeug im System, das diese Probleme löst. –

+0

Wenn Sie an Tupel wie Produkttypen denken (wie in: 'Bool' hat zwei Einwohner,' Maybe Bool' hat drei Einwohner, '(Bool, Maybe Bool)' hat sechs Einwohner), dann sind Funktionstypen Exponenten. Da 'e^(x * y) = (e^x)^y ', kann man immer eine Funktion mit dem Typ' (x, y) -> e' in eine ähnliche Funktion mit dem Typ 'y -> (x - > e) '. Das ist auf den Punkt gebracht. Da Sie solche Funktionen immer neu schreiben können (in diesem Fall zu relativ geringen Kosten), müssen Sie Multiparameterfunktionen nicht zu einem grundlegenden Konzept machen, das Ihre Sprachdefinition sonst verkomplizieren würde. –

Antwort

1

Als erstes müssen Sie sich daran erinnern, dass Haskell vollständig auf Lambda-Kalkül basiert. Es basiert auf einem wissenschaftlichen Programmiermodell (auch wenn es nicht bedeutet, dass die Sprache nur wissenschaftlichen Nutzen hat).

Was ich denke, dass Sie falsch lagen, ist, dass das nicht nur ein Argument bekommt, weil es als ein Tupel oder eine Liste gezeigt werden kann, obwohl das eine ziemlich kluge Erklärung wäre.

Haskell nimmt nur ein Argument, weil Currying:

f (x, y) = f (x) (y)

wobei f (x) eine Funktion gibt, die ein Argument annimmt. Currying ist das ganze "Funktionen, die Funktionen zurückgibt" Schema. Wenn Sie also f (x) (y) eingeben, geben Sie "y" tatsächlich an die Funktion "f (x)" weiter.

Klassisches Beispiel:

add :: a->(a->a) 
add(x) = x'+' 

Als '+' ist eine Funktion, das heißt, es ein weiteres Argument nimmt, können wir:

add(3)(5) == 8 

Wir geben nicht beide Argumente zu hinzufügen , nur eins, damit es '+' erzeugen kann, was ein anderes Argument bekommt.

Nachdem Sie das grook, wird viel Sinn machen und wir können weiter warum.

Nun, hauptsächlich syntaktischer Zucker, aber ein sehr starker. Zum Beispiel können wir Funktionen auf andere definieren basiert, ohne die Argumente zu spezifizieren:

add = '+' 

Und plötzlich zugewiesen ich Werte an Funktionen, ohne die Argumente zu erwähnen (unter der Annahme natürlich ihre Typdeklaration übereinstimmt). Dies hat viele andere Möglichkeiten und erleichtert die Abstraktion sehr.

Hier gibt es gute Antworten mit guten Beispielen: https://softwareengineering.stackexchange.com/questions/185585/what-is-the-advantage-of-currying

+0

Danke für Ihre Erinnerung, dass Haskell auf Lamda Calculus basiert. Ich habe durch Lambda-Kalkül und finden Sie die Antwort, die ich denke, ist ziemlich nah: erstens, Lamda Kalkül mit seiner Definition erweist sich als universell in dem Sinne, dass alle Berechnungen sein können dadurch aus Sicht der Marthmatiker ausgedrückt. Zweitens, eine der Lambda-Definition ist jede Funktion nimmt nur ein Argument. Dann, wie Lambda-Kalkül universell beansprucht werden kann, wenn es nicht mehrere Argumente Funktion bieten kann. Die Antwort ist natürlich, es kann nur mit Curryring (hohe Funktion). – Johnson

+0

Ja, du hast es ziemlich gut verstanden. – eduardogbg

2

Die Funktion

f x y = x + y 

den Typ hat (unter der Annahme x & y sind Integer s)

f :: Integer -> Integer -> Integer 

dies das gleiche wie

ist
g :: Integer -> (Integer -> Integer) 

Welche f bedeutet, ist eine Funktion Das nimmt eine Integer und gibt eine neue Funktion, die auch eine Integer und gibt eine Integer zurück. Curry ist der Prozess, bei dem eine Funktion, die mehrere Argumente annimmt, tatsächlich als eine Reihe von Funktionen ausgewertet wird, die ein Argument verwenden.

Currying macht es sehr einfach Funktionen teilweise anzuwenden, wie

plusTwo :: Integer -> Integer 
plusTwo = f 2 

Der obige Code einfach folgt gilt 2-f und bindet den Namen plusTwo auf die sich ergebende Funktion.

Dies macht es extrem einfach für Entwickler, gemeinsames Verhalten an einem einzigen Ort zu abstrahieren.

4

Die Entscheidung currying als die bevorzugte Methode von Funktionen Multi-Argument zu verwenden, wurde aus zwei Gründen gemacht. Erstens hat Haskell seine Wurzeln in Lambda Calculus, die Curry verwendet. Zweitens ermöglicht Curry eine einfache partielle Anwendung, eine Sprachfacette, die unbeschreiblich nützlich ist.