[Haskell-cafe] Stacking monads

David Menendez dave at zednenem.com
Fri Oct 3 15:31:29 EDT 2008


On Fri, Oct 3, 2008 at 3:10 PM, Andrew Coppin
<andrewcoppin at btinternet.com> wrote:
> Jake McArthur wrote:
>>
>> Andrew Coppin wrote:
>>>
>>> But on the other hand, that would seem to imply that every monad is
>>> trivially applicative, yet studying the libraries this is not the case.
>>
>> Actually, it is the case. It is technically possible to write:
>>
>>   instance Monad m => Applicative m where
>>     pure = return
>>     (<*>) = ap
>>
>> We don't include the above definition because it elimimates all
>> possibility of specialization.
>
> I don't follow.

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.

>> The reason for the separation of the two for many functions is so that
>> types which are instances of only one of the two can still take advantage of
>> the functionality.
>
> Well, that makes sense once you assume two seperate, unconnected classes.
> I'm still fuzzy on that first point though.

It's historical. Monad pre-dates Applicative by several years. Because
it's part of the Haskell 98 standard, no one is willing to change
Monad to make Applicative a superclass. Thus all the duplication.
(Also, many of the duplicate functions are found in the Haskell 98
report, so we can't replace them with their more-general Applicative
variants.)

>>> Foldable seems simplish, except that it refers to some odd "monoid" class
>>> that looks suspiciously like "MonadPlus" but isn't... wuh?
>>
>> A Monoid is simply anything that has an identity element (mempty) and an
>> associative binary operation (mappend). It is not necessary for a complete
>> instance of Foldable.
>
> 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 (>>=).

-- 
Dave Menendez <dave at zednenem.com>
<http://www.eyrie.org/~zednenem/>


More information about the Haskell-Cafe mailing list