On Tuesday 04 January 2011 5:24:21 am o...@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 _______________________________________________ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime