
David Menendez wrote:
For some monads, there are implementations of <*> which are more efficient than the one provided by ap. Similarly, there are ways to implement fmap which are more efficient than using liftM.
Of course, the *real* reason we don't define the instance given above is that there are instances of Applicative that aren't monads, and we want to avoid overlapping instances.
OK, now I understand. (Of course, if Applicative was already a superclass of Monad, presumably that last wouldn't still stand?)
Well, that makes sense once you assume two seperate, unconnected classes. I'm still fuzzy on that first point though.
It's historical.
Ah. So "brokenness in the name of backwards compatibility"? (Is this why we have "alternate Prelude modules"?)
Again, it looks like MonadPlus == Monad + Monoid, except all the method names are different. Why do we have this confusing duplication?
There are at least three reasons why MonadPlus and Monoid are distinct.
First, MonadPlus is older than Monoid, even though Monoid is more general.
Second, MonadPlus and Monoid have different kinds, * -> * and *, respectively. Instances of MonadPlus are more restricted, because they have to work with any type parameter, whereas instances of Monoid can place constraints.
Third, instances of MonadPlus must follow additional laws relating the behavior of mplus and mzero to return and (>>=).
OK, good. Also, I notice that the documentation for Monoid mentions that numbers form one. But that's not actually correct. Numbers for *several*! And yet, a given number type can only have *one* Monoid instance. (Or indeed, only one instance for _any_ typeclass.) How do you get round that?