存在量化类型类

时间:2012-08-10 19:00:27

标签: haskell

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>

CategoryIMonadI只是我用来表达CategoryMonad和{{1}这一类型的类型的字典。这是MonadTrans类型的超类。(/ p>)

PipeLike类型只是存储同构的以下字典:

Iso

1 个答案:

答案 0 :(得分:5)

如果这确实是一个类型类,那么字典值仅由类型p确定。特别是,cat类型仅由p确定。这可以使用关联数据类型表示。在类定义中,关联的数据类型被写成没有右侧的数据定义。

一旦您将cat表达为某种类型,其他成员就可以轻松更改为类型,就像我在MonadMonadTrans中所显示的那样。请注意,我更喜欢对复杂类型使用显式类签名。

{-# 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)