2015-09-07 25 views
7

Ich stolperte über das folgende kleine Problem. Ich bin mit Haskell Rekord Syntax zusammen mit GADTs:Mit Datensatz-Update-Syntax mit eingeschränkten GADT-Datensätze

{-# LANGUAGE GADTs #-} 

data Test a where 
    Test :: {someString :: String, someData :: a} -> Test a 

Jetzt habe ich für someData einen neuen Test Wert mit einer anderen Art erstellen möge, aber der gleiche Wert für someString (die Nutzung der Datensatzaktualisierung Syntax zu rechtfertigen):

test :: Test a -> Test Bool 
test t = t {someData = True} 

nehme ich an ein anderes Feld zum Test Konstruktor hinzu:

data Test a where 
    Test :: {someString :: String, someData :: a, someMoreData :: a} -> Test a 

Dann Ich habe beide Felder ändern meinen Code typ richtig zu halten:

test :: Test a -> Test Bool 
test t = t {someData = True, someMoreData = False} 

Bis jetzt habe ich nicht die GADT brauchen, aber jetzt möchte ich einen Typ-Klasse-Einschränkung auf den Datentyp hinzuzufügen, zum Beispiel Eq:

data Test a where 
    Test :: Eq a => {someString :: String, someData :: a} -> Test a 

Wenn auf "Update", um das Feld someData versuchen, wie im ersten Beispiel, ich ein Compiler-Fehler plötzlich bekommen:

Couldn't match type ‘a’ with ‘Bool’ 
    ‘a’ is a rigid type variable bound by 
     the type signature for test :: Test a -> Test Bool at Test.hs:18:9 
Expected type: Test Bool 
    Actual type: Test a 
Relevant bindings include 
    t :: Test a (bound at Test.hs:19:6) 
    test :: Test a -> Test Bool (bound at Test.hs:19:1) 
In the expression: t 
In the expression: t {someData = True} 

ich vermute, das ist die gleiche „p zu sein Problem "wie zuvor mit zwei Feldern vom Typ a, aber etwas implizit. Ich denke, das Wörterbuch für die Eq Klasse wird wie ein Argument des Konstruktors behandelt, genau wie wenn ich ein Feld {eqDict :: Eq a} hätte. Wenn ich recht habe, musste ich auch irgendwie das "Wörterbuchfeld" "updaten", obwohl ich nicht weiß, wie das geht. Die Frage ist, gibt es eine Möglichkeit, Satzaktualisierungssyntax zu verwenden, wenn Klassen so beteiligt sind?

Antwort