Haskell 这是什么';约束';什么意思?
在这段代码中,我试图使我的辅助函数Haskell 这是什么';约束';什么意思?,haskell,type-families,Haskell,Type Families,在这段代码中,我试图使我的辅助函数go中的第一个参数成为“type family”类型。我看到在类型中,类似的insert函数属于类型类,而在下面的示例中,它不属于类型类 我是一个新类型的家庭,所以可能我用错了,但这个错误意味着什么 {-# LANGUAGE TypeFamilies #-} -- | key class K a where -- | iterator for key type I a :: * mkI :: a -> I a --| A map data
go
中的第一个参数成为“type family”类型。我看到在类型中,类似的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
可能修复:添加修复的类型签名
这些类型变量
这包括:
{-# 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
,所以我们必须告诉它。为此,我们必须将使用的类型变量引入作用域,然后在本地签名中告诉编译器要使用哪种类型实例。首先,请注意,数据类型上下文(data(ka)=>ma b=ma b
)已从语言中删除,并且从未有用过。现在看看其他东西。您好,您如何将“go”变成顶级函数?@cdupont您只需将其移动到顶级,并将约束添加到类型签名中,go::(ka)=>(a->ia)->a->b->M a b->M a b
。不过,我不知道这对什么有用。在这种情况下,insert
中的a
和b
在go
中会有所不同。。。这就是您添加forall no的原因?@cdupont从insert
传递的参数将确定使用的a
和b
类型。在insert
范围内引用这些类型时,需要使用forall
。在顶层,类型签名中的类型独立于insert
的类型,但是参数的传递将确保被调用的go
实例使用相同的类型。
{-# 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