Arrow Classes

Ashley Yakeley ashley@semantic.org
Thu, 10 Jul 2003 22:22:56 -0700


In article <200307102002.31955.wolfgang@jeltsch.net>,
 Wolfgang Jeltsch <wolfgang@jeltsch.net> wrote:

> By the way, I strongly vote for Functor being a superclass of Monad in 
> Haskell 2.

I recently created my own Monad class in HBase instead of using the 
Prelude one. The hierarchy looks something like this:

  class HasReturn f where
   return :: a -> f a

  class Functor f where
   fmap :: (a -> b) -> f a -> f b

  class (Functor f) => FunctorApply f where
   fApply :: f (a -> b) -> f a -> f b
   fPassTo :: f a -> f (a -> b) -> f b
   (>>) :: f a -> f b -> f b

  class (FunctorApply f,HasReturn f) => FunctorApplyReturn f
  instance (FunctorApply f,HasReturn f) => FunctorApplyReturn f

  class (FunctorApplyReturn f) =>
   Monad f where
   (>>=) :: f a -> (a -> f b) -> f b

  class (Functor f) =>
   ExtractableFunctor f where
   fExtract :: (FunctorApplyReturn g) => f (g a) -> g (f a)
   fToList :: f a -> [a] -- has default definition (exercise for the 
reader)

Certain standard monadic functions, such as LiftM2, actually apply to 
classes higher up the hierarchy (FunctorApply, in this case). 
FunctorApplyReturn is a particularly useful class for "manipulating 
things in a box" when the box isn't quite a Monad.

I'm glad to hear there isn't a _serious_ cost (i.e. performance penalty) 
for fine-grained hierarchies. Yeah, so if you want to define your own 
Monad, you have to define all the other instances too. I ease this by 
providing functions such as monad_fmap and monad_fApply etc. that you 
can use for your instances.

-- 
Ashley Yakeley, Seattle WA