与Pipe
类型的启发相比,以下存在量化字典的类型等价是什么:
{-# LANGUAGE ExistentialQuantification, PolymorphicComponents #-}
data PipeD p = forall cat . PipeD {
isoI :: forall a b m r . Iso (->) (p a b m r) (cat m r a b),
categoryI :: forall m r . (Monad m) => CategoryI (cat m r) ,
monadI :: forall a b m . (Monad m) => MonadI (p a b m) ,
monadTransI :: forall a b . MonadTransI (p a b) }
我想要的粗略想法是,在给定(PipeLike p)
约束的情况下,我们可以推断(MonadTrans (p a b), Monad (p a b m)
和(使用伪代码)(Category "\a b -> p a b m r")
。< / p>
CategoryI
和MonadI
只是我用来表达Category
,Monad
和{{1}这一类型的类型的字典。这是MonadTrans
类型的超类。(/ p>)
PipeLike
类型只是存储同构的以下字典:
Iso
答案 0 :(得分:5)
如果这确实是一个类型类,那么字典值仅由类型p
确定。特别是,cat
类型仅由p
确定。这可以使用关联数据类型表示。在类定义中,关联的数据类型被写成没有右侧的数据定义。
一旦您将cat
表达为某种类型,其他成员就可以轻松更改为类型,就像我在Monad
和MonadTrans
中所显示的那样。请注意,我更喜欢对复杂类型使用显式类签名。
{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances #-}
class Pipe (p :: * -> * -> (* -> *) -> * -> *) where
data Cat p :: (* -> *) -> * -> * -> * -> *
isoI :: forall a b m r. Iso (->) (p a b m r) (Category p m r a b)
categoryI :: forall a b m. Monad m => CategoryI (Category p m r)
instance (Pipe p, Monad m) => Monad (p a b m)
instance Pipe p => MonadTrans (p a b)