Fehler beim Deklarieren einer Lambda-Funktion: zuerst eine Instanz deklarieren

8

Ich versuche, Lambda-Funktionen (d. h. anonyme Funktionen ) in Haskell zu verstehen, indem ich ein paar einfache Funktionen schreibe, die sie verwenden.

Im folgenden Beispiel versuche ich einfach, drei Parameter aufzunehmen und zwei der drei mit einer anonymen Funktion hinzuzufügen und danach den dritten Parameter hinzuzufügen. Ich erhalte eine Fehlermeldung, dass ich zuerst eine Instanz deklarieren muss.

%Vor%

Ich schätze jede Erklärung, warum mein Beispiel nicht funktioniert und / oder irgendeine Erklärung, die mir helfen würde, Lambda-Funktionen besser zu verstehen.

    
AnchovyLegend 27.03.2013, 13:38
quelle

5 Antworten

16
  

specialAdd x y z = (\x y -> x + y) + z

In diesem Beispiel versuchen Sie, einer Nummer eine Funktion hinzuzufügen, die nicht funktionieren wird. Schau dir (\x y -> x + y) + z an: es hat die Form a + b . Damit ein solcher Ausdruck funktioniert, müssen der a -Teil und der b -Teil Nummern desselben Typs sein.

Haskell ist eine etwas ungewöhnliche Sprache, daher haben die Fehlermeldungen selten die Form "das geht nicht". Also, was hier passiert ist, dass Haskell sieht, dass (\x y -> x + y) eine Funktion ist, und da in einem Ausdruck wie a + b , b vom selben Typ sein muss wie a , schlussfolgert, dass b auch a sein muss Funktion. Mit Haskell können Sie auch eigene Regeln zum Hinzufügen nicht integrierter Typen definieren. Sie können also nicht einfach einen Fehler mit dem Satz "Sie können nicht zwei Funktionen hinzufügen" angeben, sondern stattdessen lautet der Fehler "Sie haben keine Regel definiert, die es mir erlaubt, zwei Funktionen hinzuzufügen."

Das Folgende würde tun, was Sie wollen:

%Vor%

Hier wenden Sie die Funktion (\x y -> x + y) auf die Argumente x und y an und fügen dann das Ergebnis zu z hinzu.

    
Luis Casillas 27.03.2013, 15:34
quelle
10

Eine gute Möglichkeit, anonyme Funktionen zu üben, ist es, sie mit hoher Ordnungsfunktion als Falte oder Karte zu verwenden.

Verwenden Sie die Karte als Einstiegspunkt,

Grundlegende Definition der Karte,

%Vor%

Erstelle ein Beispiel,

%Vor%

Anwenden einer Karte, die wir erhalten,

%Vor%

Nun können wir die Deklaration von f weglassen und sie mit der anonymen Funktion ersetzen,

%Vor%

dann folgern wir, map f list == map (\ x- & gt; x + 1) Liste , also

%Vor%

Dann beginnen wir mit einer einfachen Funktion und sehen, wie man es in eine anonyme Funktion übersetzt und wie eine anonyme Funktion auf eine Lambda-Abstraktion angewiesen ist.

Versuchen Sie als Übung, f x = 2 * x zu übersetzen.

Jetzt komplexer, eine anonyme Funktion, die zwei Argumente braucht,

Wieder ein funktionierendes Beispiel,

%Vor%

Kann mit anonymer Funktion wie folgt umgeschrieben werden,

%Vor%

Wieder unter Verwendung der Gleichheit leiten wir her, dass add = \ x y - & gt; x + y
Darüber hinaus wie in hakell alle Funktionen sind Funktion eines Arguments, und wir können es teilweise anwenden, können wir unsere vorherige anonyme Funktion als, add = \ x - & gt; (\ y - & gt; x + y).

Dann wo ist der Trick ?? Weil ich nur die Verwendung der anonymen Funktion in eine höherwertige zeige und ausgehend davon zeige, wie dies ausgenutzt werden kann, um die Funktion unter Verwendung der Lambda-Notation neu zu schreiben. Ich meine, wie kann es Ihnen helfen zu lernen, anonyme Funktion aufzuschreiben?

Einfach, weil ich Ihnen ein existierendes Framework mit Hilfe der Funktion hoher Ordnung gezeigt habe Dieser Rahmen ist eine riesige Gelegenheit, Sie mit dieser Notation unterzubringen.
Daraus lässt sich ein unendlicher Bewegungsumfang ableiten, beispielsweise versuchen, folgendes zu tun.

%Vor%

Und so weiter ....

Zusammenfassend

Eine Funktion als

%Vor%

kann immer neu geschrieben werden als,

%Vor%

wo

%Vor%

F2 Form sind nur anonyme Funktion, eine reine Übersetzung der Funktion in Lambda-Kalkül-Form. F1 ist eine deklarative Lambda-Notation (weil wir f so definieren, wie wir es definieren und es an die anonyme F2 binden). F0 ist die übliche Schreibweise von Haskeller.

Eine letzte Anmerkung, die sich auf die Tatsache konzentriert, dass wir Klammern zwischen das Argument setzen können, das schafft eine Schließung. Dies bedeutet, dass eine Teilmenge des Funktionscodes vollständig ausgewertet werden kann, indem eine Teilmenge des Funktionsarguments verwendet wird (dh die Umwandlung in eine Form, in der keine freie Variable mehr auftritt), aber das ist eine andere Geschichte.

    
zurgl 27.03.2013 14:31
quelle
3

Hier ist die richtige Form:
specialAdd a b c = ((\x y -> x + y) a b) + c

Beispiel von Lernen Sie ein Haskell ...:
zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

Tolle Erklärung: Ссылка

    
Vladimir 27.03.2013 13:41
quelle
2

Von was ich verstehe Labbda / anonyme Funktionen helfen Ihnen, eine Funktion "Inline" zu deklarieren, ohne einen Namen zu geben. Das "\" (ASCII für das Griechische, λ) steht vor den Variablennamen für den Ausdruck, der dem "- & gt;" folgt. Zum Beispiel

%Vor%

ist eine anonyme (Lambda) -Funktion ähnlich wie (+). Sie benötigt zwei Parameter vom Typ Num und gibt ihre Summe zurück:

%Vor%

Ihr Beispiel funktioniert nicht, weil, wie bereits erwähnt, die rechte Seite eine Lambda-Funktion (\ xy - & gt; x + y) als Parameter für den Operator (+) verwendet ist standardmäßig nur für Parameter vom Typ Num definiert. Etwas von der Schönheit der Lambda-Funktion kann in ihrer "anonymen" Verwendung sein. Vladimir zeigte, wie Sie die Lambda-Funktion in Ihrer Deklaration verwenden können, indem Sie ihr die Variablen von der linken Seite übergeben. Eine "anonymere" Verwendung könnte einfach sein, sie mit Variablen zu benennen, ohne der Funktion einen Namen zu geben (daher anonym). Zum Beispiel

%Vor%

Oder in einem längeren Ausdruck (wie in Ihrer Beispieldeklaration), z. B.

%Vor%     
גלעד ברקן 28.03.2013 04:21
quelle
1

Sie versuchen, (+) als etwas wie (Num a) => (a -> a -> a) -> a -> ?? zu verwenden, was nicht korrekt ist.

(+) ist in der Klasse Num definiert und (a - & gt; a - & gt; a) ist keine Instanz dieser Klasse.

Was genau wollen Sie erreichen?

    
thoferon 27.03.2013 13:42
quelle

Tags und Links