
I got the impression you could define anthing you liked for mzero and mplus - providing the laws are upheld?
I agree that a law-based approach is the correct one. The "Monad laws" are well known, equivalent laws for Functor don't seem to be talked about so much but I doubt there'd be any argument about them, given that Functor is supposed to represent a well-defined concept in category theory. These are found in [1]: fmap id = id fmap (a . b) = (fmap a) . (fmap b) I think it would be helpful if all these classes came with their laws prominently attached in their Haddock documentation or wherever. The trouble with MonadPlus is that the precise set of associated laws is either unspecified or not the most useful (I assume there's a paper on the class somewhere). I think everyone can agree on these: mplus mzero a = a mplus a mzero = a mplus (mplus a b) c = mplus a (mplus b c) mzero >>= a = mzero But what about this? a >> mzero = mzero It's satisfied by [] and Maybe, but not IO (for instance, when a is 'putStrLn "Hello"'), but IO has been declared an instance of MonadPlus. And then there are the two I gave: (mplus a b) >>= c = mplus (a >>= c) (b >>= c) ...which is satisfied by [], but not Maybe or IO. mplus (return a) b = return a ...which is satisfied by Maybe and IO, but not [], although your alternative declaration would make [] satisfy this and not the previous one. [1] Mark P. Jones, _Functional Programming with Overloading and Higher-Order Polymorphism_, 1995 -- Ashley Yakeley, Seattle WA