2014-11-13 3 views
9

Nach von this question, ich bin mir nicht sicher, warum diese beiden Code-Snippets ganz andere Fehler erzeugen:Warum erzeugt GHC hier einen Gleichheitsbedingungsfehler und nicht einen Typabgleichfehler?

zu diesem Verhalten
f :: a -> b 
f x = x 
-- Couldn't match expected type `b' with actual type `a' 
-- In the expression: x 

g :: Monad m => a -> m b 
g x = return x 
-- Could not deduce (a ~ b) from the context (Monad m) 
-- In the first argument of `return', namely `x'. 

Was die Regel Anstieg geben wird?

Es ist nicht gut lesbar, selbst für jemanden, der mit Standard-Haskell vertraut ist; Die Gleichheitsbedingung (a ~ b) erfordert eine Sprachenerweiterung.

Beachten Sie, dass, wie chi wies darauf hin, das bloße Vorhandensein einer Beschränkung der Beschränkung Fehler auslöst:

class C a 

h :: C a => a -> b 
h x = x 
-- Could not deduce... 

(Eine leere Einschränkung, () => a -> b, gibt dem Spiel nicht die Einschränkung Fehler.)

+2

Fügen Sie einen beliebigen Kontext zu 'f' hinzu und Sie werden den Gleichheitsbedingungsfehler auslösen: z. 'f :: Show a => a -> b' – chi

+1

Während nicht streng falsch, ist die Meldung" Konnte nicht ableiten (a ~ b) "in diesem Fall für einen Anfänger wahrscheinlich nicht sehr gut, der nicht weiß, was das' ~ 'Symbol bedeutet. Was "warum" angeht - ich würde sagen, es ist ein Fehler. – user2407038

Antwort

6

Ich glaube nicht, dass es eine kürzere Antwort gibt, als in GHC-Interna zu graben, um zu verstehen, warum.

Wenn Sie GHC mit dem Schalter -ddump-tc-trace ausführen, können Sie ein ziemlich langes Protokoll des Tychecking-Prozesses erhalten. Insbesondere dann, wenn Sie es auf diesem Code ausführen:

f :: a -> b 
f x = x 

class C a 

h :: C c => c -> d 
h x = x 

Sie, dass die Typprüfung a vs b sehen kannst, und Typprüfung c vs d schreiten genau die gleiche Art und Weise in beiden Fällen gipfeln in den folgenden zwei ungelösten Einschränkungen (Ausgang ist von GHC 7.8.2):

tryReporters { [[W] cobox_aJH :: c ~ d (CNonCanonical)] 
... 
tryReporters { [[W] cobox_aJK :: a ~ b (CNonCanonical)] 

mit ein bisschen mehr in den Kaninchenbau in TcErrors, Sie, dass für Gleichheiten auf skolems sehen können, die Fehlermeldung über misMatchOrCND bekommt tryReporters schließlich zu erstellen, wh Ich habe einen expliziten Sonderfall für leere Kontexte:

misMatchOrCND :: ReportErrCtxt -> Ct -> Maybe SwapFlag -> TcType -> TcType -> SDoc 
-- If oriented then ty1 is actual, ty2 is expected 
misMatchOrCND ctxt ct oriented ty1 ty2 
    | null givens || 
    (isRigid ty1 && isRigid ty2) || 
    isGivenCt ct 
     -- If the equality is unconditionally insoluble 
     -- or there is no context, don't report the context 
    = misMatchMsg oriented ty1 ty2 
    | otherwise 
    = couldNotDeduce givens ([mkTcEqPred ty1 ty2], orig) 
+0

Naiv lesen 'misMatchOrCND', sollte nicht' isRigid ty1 && isRigid ty2' ist 'True'? Sind hier nicht alle Typen im Spiel starr? –

+0

Siehe die Definition von 'isRigid' im selben Modul; Ich sehe nicht, wie True für irgendwelche Variablen überhaupt zurückgegeben werden kann. Beachten Sie, dass es nicht das gleiche wie 'isRigidOrSkol' ist. – Cactus

Verwandte Themen