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?
Schade, ich denke, ich muss bei meinem Workaround bleiben. Danke für deine schnelle Antwort. –