2015-04-21 2 views
5

Betrachten Sie das folgende:Monomorphismus Einschränkung ausgelöst, wenn generische Instanz definiert

{-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs, MultiParamTypeClasses #-} 

type family F r 

class (Functor t) => T t r where 
    fromScalar :: r -> t r 

data Foo t r where 
    Foo :: t (F r) -> Foo t r 
    Scalar :: r -> Foo t r 

toF :: r -> F r 
toF = undefined 

convert :: (T t (F r)) 
    => Foo t r -> Foo t r 
convert (Scalar c) = 
    let fromScalar' = fromScalar 
    in Foo $ fromScalar' $ toF c 

Dieser Code mit GHC 7.8.4 kompiliert.

Wenn ich hinzufügen, eine generische Instanz für T (die FlexibleInstances erfordert):

instance (Functor t, Num r) => T t r 

GHC klagt:

Could not deduce (Num (F r)) arising from a use of ‘fromScalar’ 
    from the context (T t (F r)) 
     bound by the type signature for 
       convert :: (T t (F r)) => Foo t r -> Foo t r 
     at Main.hs:(17,12)-(18,23) 
    In the expression: fromScalar 
    In an equation for ‘fromScalar'’: fromScalar' = fromScalar 
    In the expression: 
     let fromScalar' = fromScalar in Foo $ fromScalar' $ toF c 

Ich erinnerte mich an this question, aber es scheint zu sein, einige wichtige Unterschiede. Zuerst und am wichtigsten, GHC beklagte sich nicht Vorinstanz. Zweitens habe ich nicht RankNTypes, die im Kern des Problems mit dieser Frage schien. Schließlich hilft das Hinzufügen von NoMonoLocalBinds nicht. Seltsamerweise, Hinzufügen NoMonomorphismRestrictiontut ändern Sie die Fehlermeldung von der Beschwerde über fromScalar zu der gleichen Nachricht über fromScalar'.

Natürlich ist das Problem ScopedTypeVariables durch Hinzufügen einer Art Signatur fromScalar und das Hinzufügen fixiert werden kann:

convert :: forall t r . (T t (F r)) 
    => Foo t r -> Foo t r 
convert (Scalar c) = 
    let fromScalar' = fromScalar :: F r -> t (F r) 
    in Foo $ fromScalar' $ toF c 

Ich bin bereit, etwas verrückt mit monomorphen Arten zuzugestehen ist hier bei der Arbeit, auch wenn die Einschränkungen entfernen hat nicht geholfen. Meine Frage ist: Warum wird die Beschränkung durch das Hinzufügen einer generischen Instanz ausgelöst? Noch wichtiger, warum versucht GHC, die generische Instanz zu vergleichen, anstatt die T (F r)-Einschränkung zu verwenden? Das scheint einfach falsch zu sein und riecht nach this bug.

+2

Sie haben Recht, es kann der gleiche Fehler sein. Es ist wahrscheinlich einen Test wert, wenn es jetzt in HEAD/dem Zweig 7.10.2 behoben ist. Das Problem scheint zu sein, dass die hinzugefügte Instanz GHC zwei Möglichkeiten bietet, die 'T t (Fr) '- Einschränkung zu reduzieren, die sich aus der Verwendung von' fromScalar' ergibt, und aus irgendeinem Grund wählt GHC die Instanz statt der Wörterbuch zum Umwandeln bereitgestellt. – kosmikus

+0

Wenn das stimmt, ist mein Glück schrecklich ... Ich habe es geschafft, denselben Fehler in einer völlig anderen Umgebung wieder zu finden! – crockeea

+0

Es stellt sich heraus, dass sich dieser Fehler von [# 10195] unterscheidet (https://ghc.haskell.org/trac/ghc/ticket/10195). Sie können mehr [hier] (https://ghc.haskell.org/trac/ghc/ticket/10338) lesen. – crockeea

Antwort

0

Dies ist GHC Fehler #10338. Leider sieht es nicht so aus, als würde es bald gelöst werden.