Monads and Maybe

Ashley Yakeley ashley@semantic.org
Fri, 22 Aug 2003 18:58:23 -0700


In article <Pine.GSO.4.53.0308210041300.8238@altair.dur.ac.uk>,
 C T McBride <c.t.mcbride@durham.ac.uk> wrote:

> My point, however, is not to use <$> with that type, but the more general
> 
>   class Fun f where
>     eta :: x -> f x
>     (<$>) :: f (s -> t) -> f s -> f t
> 
> Is there a better name for Fun? Is it ancient and venerable?

Ancient and venerable almost certainly, but not well-known. Lost 
Knowledge of Haskell, perhaps. People keep reinventing this class (which 
is a subclass of Functor btw).

In HBase I call it FunctorApplyReturn. My hierarchy looks more or less 
like this:

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

  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
    fPassTo = liftF2 (\a ab -> ab a)

  liftF2 func fa = fApply (fmap func fa)

  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
    fail :: String -> f a;
    fail = error;
 
Certain functions that seem to require Monads actually work with any 
FunctorApplyReturn. For instance:

  class (Functor f) => ExtractableFunctor f where
    fExtract :: (FunctorApplyReturn m) => f (m a) -> m (f a)

  for :: (ExtractableFunctor f,FunctorApplyReturn m) =>
    (a -> m b) -> (f a -> m (f b));
  for foo fa = fExtract (fmap foo fa)

All sorts of useful types such as [] and Maybe can be made 
ExtractableFunctors. And then 'for' can iterate on them.

IMO something like all this should be in the standard libraries. The 
downside is that people would have to make instances for HasReturn, 
Functor and FunctorApply with every Monad instance.

-- 
Ashley Yakeley, Seattle WA