0

Ich habe Probleme, die Begründung hinter Typen Signaturen in Haskell zu verstehen.Rechts-Assoziativität in Typ-Signaturen von Funktionen

1) Wie man sagt, ist -> rechts assoziativ, bedeutet es, dass es in der ähnlichen Weise verstanden werden könnte, zum Beispiel 4^(2^(3^2))?

2) Art Signatur von einfacher Funktion, um meine Zweifel zum Ausdruck bringen (so, wie ich es verstehen, zu erklären, werde ich a, b, c statt Num a => a ‚s oder Int‘ s) verwenden:

myAdd :: a -> b -> c 
myAdd x y = x+y 

es bedeutet, dass Funktionsparameter a und kehrt Funktion, die b nimmt nimmt und kehrt schließlich c

Aber es könnte so neu geschrieben werden:

myAdd :: (a->(b->c)) 

Da die meisten des Lernmaterials besagen, dass c in unserem Beispiel das Ergebnis der Funktion MyAdd ist, warum nach der Verwendung von Klammern bedeutet dies, dass erste ‚Operation‘ b->c ist? Wie kann ich aus dieser Art Signatur die Reihenfolge der durchgeführten Operationen ableiten?

3) ich eine Aufgabe gegeben wurde

map f xs 

mit foldr, (.) und (:), die in Folge zu implementieren:

map f xs = foldr ((:) . f) [] xs 

keine Probleme der oben genannten Funktionen Ich habe Verständnis der Funktionsweise , aber hier kommen wir wieder - Typ Signaturen. Wenn wir annehmen, dass diese Namen vereinheitlicht sind, so dass der Typ a den gleichen Typ in allen Verträgen darstellt, scheint es, dass c und d in Bezug auf a und b ausgedrückt werden können. In der Mathematik wäre eine ähnliche Aufgabe wahrscheinlich ganz einfach, aber wie gehe ich in Haskell vor?

map :: (a -> b) -> [a] -> [b] 
foldr :: (a -> c -> c) -> c -> [a] -> c 
(:) :: b -> ([b] -> [b]) 
(.) :: (b -> d) -> (a -> b) -> a -> d 
+3

Bitte fokussieren Sie Ihre Frage auf einen korrekt beantwortbaren Aspekt. – leftaroundabout

+0

Die Operation in Teil 1 erstellt einen Funktionstyp. Der als "zuerst" angelegte Funktionstyp ist "b -> c". Dies wird dann in den größeren Funktionstyp 'a -> (b -> c) 'kombiniert. Beachten Sie, dass all dies auf der Ebene der Typen liegt und nicht auf der Ebene der Werte. '->' ist etwas, das zwei Typen akzeptiert und Ihnen einen Typ zurückgibt: die Art der Funktionen vom linken Typ zum richtigen Typ. Um die Dinge etwas konkreter zu machen, wenn Sie '->' die Typen 'Char' und' Int' angeben, gibt es Ihnen die Art der Funktionen von 'Char' nach' Int' zurück. –

Antwort

5

Verwenden Sie Ihre Schreibweise, in

myAdd :: a -> b -> c 
myAdd x y = x+y 

Sie richtig den Typ als a -> (b->c) interpretieren, aber dann gehen Sie auf zeigen, dass die Berechnung in b -> c irgendwie zuerst durchgeführt wird.

Wenn etwas wie myAdd 2 10 ausgewertet wird, ist die Funktionsauswertung von links nach rechts.

1) Zuerst wird myAdd 2 ausgewertet. Das Ergebnis dieser Auswertung ist die Funktion, die eine gegebene Nummer y an 2 + y sendet.In der Tat ist die Definition von myAdd die gleiche wie

myAdd x = \y -> x+y 

2) Diese letzte Funktion auf das Argument angewendet wird dann 102 + 10 = 12

So zu ergeben, das Recht Assoziativität von -> im Typ Ausdruck entspricht nicht einer Reihenfolge von rechts nach links der Berechnung in der Funktion Auswertung. Tatsächlich ist die Funktionsbewertung linksassoziativ: myAdd 2 10 ist dasselbe wie (myAdd 2) 10.

+0

Ich verstehe Links-Assoziativität der Funktion Auswertung, aber nicht rechts-Assoziativität von '->' in der Art Ausdruck. –

+5

Typ Ausdrücke sagen was etwas * ist * - sie geben keine Reihenfolge der Berechnung an. 'a -> (b -> c)' besagt, dass ein Element des Typs 'a' auf etwas verweist, das' eine' Funktion ist, die Elemente des Typs 'b' an Elemente des Typs' c' sendet. Betrachten Sie es als logische Gruppierung von Bestandteilen, nicht als zeitliche Gruppierung von Berechnungen. –