4

What is the type-class equivalent to the following existentially quantified dictionary, inspired by the Pipe type:

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

The rough idea I'm going for is trying to say that given the (PipeLike p) constraint, we can then infer (MonadTrans (p a b), Monad (p a b m) and (using pseudo-code) (Category "\a b -> p a b m r").

The CategoryI and MonadI are just the dictionary equivalents of those type-classes that I use to express the idea that Category, Monad, and MonadTrans are (sort of) super-classes of this PipeLike type.

The Iso type is just the following dictionary storing an isomorphism:

data Iso (~>) a b = Iso {
    fw :: a ~> b ,
    bw :: b ~> a }
4

1 回答 1

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)
于 2012-08-10T21:35:51.107 回答