Qu'est-ce que ce « A` variable de type` Ambigu dans la contrainte » moyenne?
-
27-10-2019 - |
Question
Dans ce code, je suis en train d'avoir le premier paramètre dans ma fonction de travailleur go
un type « famille type ». Je vois que dans le type une fonction similaire insert
appartient à la classe de type, alors que dans mon exemple ci-dessous il ne fonctionne pas.
Je suis nouveau à taper les familles alors peut-être que je les utilise mal, mais qu'est-ce que cela signifie d'erreur?
{-# 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
variable de type Ambiguous `a » dans la contrainte:
`K a' arising from an expression type signature at Data/Map2.hs:167:10-33
probable fix: ajouter une signature de type fixe ces variables de type (s)
La solution
compiles:
{-# 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
Qu'est-ce que j'ai changé et pourquoi?
D'abord, je suppose que vous vouliez la contrainte sur M
, donc j'utilisé une forme de définition de type qui impose la contrainte et le rend disponible sur les sites d'utilisation, un GADT
.
En second lieu, le problème de votre GHC se plaint, l'ambiguïté. Le point est qu'il n'y a aucun moyen pour le compilateur Déduire qui mkI
il devrait utiliser, donc nous devons le dire. Pour cela, nous devons apporter les variables de type utilisées dans le périmètre puis dire au compilateur dans la signature locale par exemple le type d'utilisation.