O que faz este Ambíguos variável de tipo `a` em restrição' significa?
-
27-10-2019 - |
Pergunta
Neste código eu estou tentando ter o primeiro parâmetro na minha função de trabalho go
ser um "tipo de família", escreve.Eu vejo que no tipo digite as famílias documentação um semelhante insert
função pertence ao tipo de classe, enquanto que no meu exemplo abaixo, ele não.
Eu sou novo tipo de famílias, talvez por isso eu estou usando errado, mas o que significa este erro significa?
{-# 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
Ambíguo variável de tipo `a' em restrição:
`K a' arising from an expression type signature at Data/Map2.hs:167:10-33
Provável correcção:adicionar um tipo de assinatura que corrige estes tipo de variável(s)
Solução
Isso 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
O que eu mudei e por quê?
Primeiro, eu achei que você queria que a restrição na M
, então eu usei uma forma de definição do tipo que impõe a restrição e o torna disponível, em uso de sites, uma GADT
.
Segundo, o problema de seu GHC queixaram-se, a ambigüidade.O ponto é que não há nenhuma maneira para que o compilador para deduzir que mkI
ele deve usar, então temos que dizer a ele.Para isso, temos de trazer o tipo de variáveis utilizadas no escopo e, em seguida, informar ao compilador no local de assinatura que tipo de instância para o uso.