In opposition of Functor as super-class of Monad

Dan Doel dan.doel at gmail.com
Tue Jan 4 14:29:07 CET 2011


On Tuesday 04 January 2011 5:24:21 am oleg at okmij.org wrote:
> Method A: just define bind as usual
> 
> > instance (Functor (Iteratee el m),Monad m) => Monad (Iteratee el m) where
> > 
> >     return = IE_done
> >     
> >     IE_done a   >>= f = f a
> >     IE_cont e k >>= f = IE_cont e (\s -> k s >>= docase)
> >     
> >      where
> >      docase (IE_done a, stream)   = case f a of
> >      
> >                  IE_cont Nothing k -> k stream
> >                  i                 -> return (i,stream)
> >      
> >      docase (i, s)  = return (i >>= f, s)
> 
> Although we must state the constraint (Functor (Iteratee el m)) to
> satisfy the super-class constraint, we have not made any use of the
> constraint.

This, at least, is false. If Functor is a superclass of Monad, then Monad m 
implies Functor m, which implies Functor (Iteratee el m). So Monad m is a 
sufficient constraint for the instance.

As for the other concerns, I think the closest fix I've seen is to allow 
subclasses to specify defaults for superclasses, and allow instances for 
subclasses to include methods for superclasses. So:

  class Functor m => Monad m where
    return :: a -> m a
    (>>=)  :: m a -> (a -> m b) -> m b

    fmap f x = x >>= return . f

This has its own caveats of course. And in this case, it seems to 
overconstrain the functor instance, since presumably we'd end up with:

  instance Monad m => Monad (Iteratee el m) where ...
    ==>
  instance Monad m => Functor (Iterate el m) where ...

I'm not sure what to do about that.

-- Dan



More information about the Haskell-prime mailing list