Was bedeutet diese "mehrdeutige Typvariable" a "in der Einschränkung"?
-
27-10-2019 - |
Frage
In diesem Code versuche ich, den ersten Parameter in meiner Worker-Funktion go
vom Typ 'type family' zu haben.Ich sehe, dass in der Typ Dokumentation zu Typfamilien eine ähnliche insert
-Funktion zur Typklasse gehört, während in meinem Beispiel untenes tut nicht.
Ich bin neu in der Eingabe von Familien, daher verwende ich sie möglicherweise falsch, aber was bedeutet dieser Fehler?
{-# LANGUAGE TypeFamilies #-}
-- | key
class K a where
-- | iterator for key
type I a :: *
mkI :: a -> I a
--| A map
data (K a) => M a b = M a b
insert :: (K a) => a -> b -> M a b -> M a b
insert = go mkI -- <<< PROBLEM
where
go o a b m = m
Mehrdeutige Typvariable "a" in der Einschränkung:
`K a' arising from an expression type signature at Data/Map2.hs:167:10-33
Wahrscheinlicher Fix: Fügen Sie eine Typensignatur hinzu, die das Problem behebt diese Typvariablen
Lösung
Dies kompiliert:
{-# LANGUAGE TypeFamilies, GADTs, ScopedTypeVariables #-}
-- | key
class K a where
-- | iterator for key
type I a :: *
mkI :: a -> I a
-- | A map
data M x y where
M :: K a => a -> b -> M a b
insert :: forall a b. (K a) => a -> b -> M a b -> M a b
insert = go mkI
where
go :: (a -> I a) -> a -> b -> M a b -> M a b
go o a b m = m
Was habe ich geändert und warum?
Zuerst habe ich angenommen, dass Sie die Einschränkung für M
haben möchten, also habe ich eine Form der Typdefinition verwendet, die die Einschränkung erzwingt und an Verwendungsorten verfügbar macht, einen GADT
.
Zweitens das Problem, über das sich Ihr GHC beschwert hat, die Mehrdeutigkeit.Der Punkt ist, dass es für den Compiler keine Möglichkeit gibt, abzuleiten, welchen mkI
er verwenden soll, also müssen wir es sagen.Dazu müssen wir die verwendeten Typvariablen in den Geltungsbereich bringen und dann dem Compiler in der lokalen Signatur mitteilen, welche Typinstanz verwendet werden soll.