在这段代码中,我试图让我的worker函数go
中的第一个参数成为'type family'类型。我在类型type families documentation中看到类似的insert
函数属于类型类,而在下面的示例中则没有。
我是新手来打字,所以也许我错了,但这个错误是什么意思?
{-# 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
约束中的模糊类型变量`a':
`K a' arising from an expression type signature at Data/Map2.hs:167:10-33
可能的修复:添加修复的类型签名 这些类型变量
答案 0 :(得分:10)
编译:
{-# 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
我改变了什么?为什么?
首先,我假设您希望约束M
,因此我使用了一种类型定义形式来强制执行约束并使其在使用站点上可用,GADT
。
其次,GHC抱怨的问题,含糊不清。关键是编译器无法推断它应该使用哪个 mkI
,所以我们必须告诉它。为此,我们必须将使用的类型变量带入范围,然后告诉编译器在本地签名中使用哪个类型实例。