¿Qué significa esta 'variable de tipo ambigua `a` en la restricción'?
-
27-10-2019 - |
Pregunta
En este código estoy intentando tener el primer parámetro en mi función de trabajo. go
ser un tipo de 'familia tipográfica'.eso lo veo en el tipo documentación de familias tipográficas un similar insert
La función pertenece a la clase de tipo, mientras que en mi ejemplo siguiente no.
Soy nuevo en el mundo de las familias tipográficas, así que tal vez las esté usando mal, pero ¿qué significa este error?
{-# 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 tipo ambigua `a' en la restricción:
`K a' arising from an expression type signature at Data/Map2.hs:167:10-33
Solución probable:Agregue una firma de tipo que corrija estos tipos de variables (s)
Solución
Esto compila:
{-# 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é he cambiado y por qué?
Primero, supuse que querías la restricción en M
, así que utilicé una forma de definición de tipo que impone la restricción y la hace disponible en los sitios de uso, una GADT
.
En segundo lugar, el problema del que se quejó su GHC: la ambigüedad.El punto es que no hay manera de que el compilador deduzca cual mkI
debería usarse, así que tenemos que decírselo.Para eso, debemos incluir las variables de tipo utilizadas en el alcance y luego decirle al compilador en la firma local qué instancia de tipo usar.