
Am Samstag, 22. Januar 2005 10:09 schrieb Ashley Yakeley:
In article <41F211FB.3030706@imperial.ac.uk>,
Keean Schupke
wrote: This fits the above description, but I don't see how the following can be true:
(mplus a b) >>= c = mplus (a >>= c) (b >>= c)
Try it (and my test code) with [], which is an instance of MonadPlus. mplus is defined as (++) for [].
Well, mathematically, a MonadPlus m is a functor into the category of monoids. With the appropriate options, we can write instance Monad m => Functor m where fmap = liftM -- so we see that any Monad is a functor (if >>= is properly defined) -- instance MonadPlus m => Monoid (m a) where mempty = mzero mappend = mplus and feed that into ghc or hugs. Only the monoid Maybe a is not very nice (nor is the monoid IO a),since the second argument of the composition is in general ignored. Actually we can make every nonempty set a monoid in this way, choose an element x1 and define the composition (#) by x1 # x = x, y # z = y, if y /= x1. Now the second argument to (>>=) is an arbitrary function into some monoid and there is no reason why (>>= c) should be a morphism in the category of monoids -- for the trivial monoids just defined, it would naturally be simply c itself. It is a nice feature of lists that (>>= c) is a homomorphism there, but that is only so because (>>=) is appropriately defined. However, (>> k) is, if I see it correctly, a monoid-homomorphism in all these cases -- though somewhat boring. So I think, rather than separating mplus, one should think about whether it is sensible to make Maybe and IO instances of MonadPlus in the first place. I don't know nearly enough of the innards of Haskell to form a valuable opinion of that, but perhaps somebody could enlighten me? Regards, Daniel