2015-01-21 8 views
11

Wenn Kontexte auf eine Art Signatur zu schreiben, normalerweise würde ich Haskell Multiple Kontexte - currying?

f :: (Enum a, Ord a) => a -> a 

aber durch schiere pures Glück etwas wie

tun fand ich, dass diese kompiliert und scheint identisch zu arbeiten, zumindest auf GHC 7.8:

f :: Enum a => Ord a => a -> a 

Was sind die theoretischen oder praktischen Unterschiede zwischen den beiden? Ist der zweite weniger orthodox? Die Haskell report scheint die zweite Form nicht zu erwähnen, und ich habe sie nie irgendwo benutzt gesehen. Related question.

+0

SPJ präsentierte einmal einen Vortrag, in dem er erklärte, welche Einschränkungen kompilieren. https://www.youtube.com/watch?v=6COvD8oynmI - Kurz gesagt, sie sind Funktionsargumente in ihren eigenen. – AJFarmar

Antwort

6

Die beiden Versionen sind identisch. Constraints und forall -s werden an den Anfang des Bereichs ausgegeben, wenn sie nicht bereits vorhanden sind. Zum Beispiel sind die folgenden Definitionen gelten:

foo :: a -> a -> Num a => a 
foo = (+) 

bar :: a -> forall b. b -> a 
bar = const 

Aber :t foo druckt Num a => a -> a -> a und :t bar druckt a -> b -> a (die forall a b. a -> b -> a entspricht).

GHC unterstützt keine polymorphen Rückgabetypen. Daher werden die Constraints und die Quantifizierer ausgeflaggt. Ich denke, es könnte auch eine gültige Designwahl für GHC gewesen sein, um Fehler zu werfen.

+0

Obwohl die erste sollte ein Parser Fehler sein, wenn man die Grammatik von 2010 konsequent folgt. Auf der anderen Seite ist [GHC's Parser] (https://github.com/ghc/ghc/blob/master/compiler/parser/Parser.y) voller Dinge, die ich nicht verstehen kann. – Zeta

+0

FTR, hier ist der relevante Teil des Parsers: https://github.com/ghc/ghc/blob/851ed7211fb18fea938be84c99b6389f6762b30d/compiler/parser/Parser.y#L1082 – kirelagin