Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Herbert Valerio Riedel hvr at gnu.org
Sun Oct 4 00:15:36 UTC 2015


On 2015-10-03 at 03:01:12 +0200, Henrik Nilsson wrote:

[...]

>> Have you surveyed the actual number of books out
>> there which show how to implement Monad instances and
>> how many of them would be affected?
>
> No. we have not. But ought not the burden of proof rest
> with those who are proposing a non-essential breaking
> change? If not, why not?

Well, afaik the books commonly used in teaching are largely based on
Haskell 98 or Haskell 2010.

( IMO, the problem here is rather the expectation that the latest GHC
  would still provide a Haskell 2010 library environment, even though
  the few books based on GHC for the most part let the reader run GHC in
  default mode and mention neither `-XHaskell2010` nor `-package
  haskell2010`.  And yes, GHC 7.10 effectively had to drop support for
  `-package haskell2010`. Otoh, There's several Linux distributions
  still stuck on GHC 7.6.3 (e.g. Debian & Ubuntu) or even older.
   
  Btw, would the concern be addressed if a future GHC would recover a
  legacy Haskell2010 library environment?
)

All books I've looked at so far will undoubtedly have their examples
defining `Monad` instances be broken under the next Haskell Report, even
*without* the MRP which simplifies the Haskell Report and is surely more
desirable from a pedagogical point of view as well.

----------------------------------------------------------------------------

For instance, in Graham Hutton's Book the section about defining Monad
instances in chapter 10[1] is rather short (defining `Monad` instances
is not an essential part of that book) and presents the Monads
type-class literally as

  class Monad m where
     return :: a -> m a
     (>>=)  :: m a -> (a -> m b) -> m b

and goes on to claim

| Using this declaration, parsers and interactive programs can then be
| made into instances of the class of monadic types, by defining the two
| member functions in the appropriate manner:

And this will clearly not apply anymore under the next Haskell Report.
On the bright side, `fail` is not mentioned, so at least it won't break
under the MonadFail change.

----

Richard Bird's "Thinking Functionally with Haskell" from 2014 sticks to
Haskell2010, and presents the `Monad` class exactly like Graham's book
(i.e. providing only `return` and `(>>=)`). Curiously, even though
published in 2014, `Applicative` isn't mentioned anywhere in the
book. In any case, this Book's `Monad`-instance examples will be broken
as well under a new Haskell Report due to the AMP change.

----

Simon Thompson's "Haskell - the Craft of Functional Programming, 3ed"
(2011), on the other hand presents the `Monad` class exactly as written
into the Haskell 2010 Report, namely:


   class Monad m where
    (>>=)   :: m a -> (a -> m b) -> m b
    return  :: a -> m a
    (>>)    :: m a -> m b -> m b
    fail    :: String -> m a

    m >> k  =  m >>= \_ -> k
    fail s  = error s


Consequently, `Monad`-defining examples in that book break on accounts
of both, AMP *and* MonadFail changes.

----

The "Real World Haskell" book predates Haskell 2010 by a few years but
features the `Applicative` class. `Monad`-instance examples contained in
the book break on accounts of AMP and MonadFail as well.

----

Miran Lipovaca's very popular "Learn You a Haskell for Great Good" (2011)
book is written in a more casual style and targets mostly Haskell
2010. The `Monad` class is presented with the 4 methods according to the
Haskell 2010 Report.[2]

The `Applicative` class is mentioned and the missing superclass
relationship is pointed out:

| Shouldn't there be a class constraint in there along the lines of
| `class (Applicative m) => Monad m where` so that a type has to be an
| applicative functor first before it can be made a monad? Well, there
| should, but when Haskell was made, it hadn't occured to people that
| applicative functors are a good fit for Haskell so they weren't in
| there.

It's also noteworthy that the book has to explain why there are two
different verbs for the same purpose:

| The first function that the Monad type class defines is `return`. It's
| the same as `pure`, only with a different name. Its type is `(Monad m)
| => a -> m a`. It takes a value and puts it in a minimal default
| context that still holds that value. In other words, it takes
| something and wraps it in a monad. It always does the same thing as
| the `pure` function from the `Applicative` type class, which means
| we're already acquainted with `return`. We already used `return` when
| doing I/O. We used it to take a value and make a bogus I/O action that
| does nothing but yield that value.

The `MonadFail` class, however, is neither mentioned nor anticipated. So
LYAH will need to be updated as well regarding AMP and MonadFail induced
breakages.

----

Finally, Alejandro Serrano Mena's more practical "Beginning Haskell" book
also provides to the full Haskell 2010 `Monad` class
definition. The `Applicative` class is described as well. However, the
book was clearly written in the knowledge of the upcoming AMP:

| If any Monad instance is also an instance of Functor, why is this
| relation not shown in the declaration of those classes? This is a
| historical accident, and you should expect Functor to soon become a
| superclass of Monad . In the meantime, you should ensure that you have
| an instance of Functor for each of your Monad instances: you can build
| one easily using the aforementioned liftM function.

as well as

| The fact that Applicative does not appear as a superclass of Monad is
| again a historical accident: the Monad concept was used widely much
| earlier than the concept of Applicative . For compatibility reasons,
| Monad hasn’t changed its definition to include any of Functor or
| Applicative as superclasses. This will change soon, though, and the
| full hierarchy Functor , then Applicative , then Monad will be
| apparent in the type classes.

But at the time of writing the MonadFail proposal couldn't be
foreseen.

----------------------------------------------------------------------------

These may not be all the Haskell books out there, but these examples
clearly show that we've already set a precedent with the AMP and the
MonadFail proposal alone. There are a few other base-library transitions
already happened or in mid-flight that have a similar effect on
published books and materials which leave the boundaries of the Haskell
2010 Library Report.

So if the primary argument is that published literature shouldn't get
broken. Well, that's already happened. And there will unavoidably be
incompatible changes between Haskell2010 and Haskell201x.


The point of this Monad-of-no-return Proposal was to provide the formal
basis to be able to write the AMP into the next upcoming Haskell Report
in a sensible way (and I think we can all agree that this is the right
thing to do as there is no good justification for including the
`Monad(return)`-method in an Haskell Report integrating the AMP changes)


However, one thing that seems to have been mostly ignored in this whole
discussion so far is that just because the next Haskell Report
anticipates the removal of `return` and `(>>)` as methods this doesn't
mean that GHC's `base` library has to follow suit immediately!

The proposal states that phase 2 can happen in GHC 8.2 *or later*. This
could also mean e.g. GHC 8.4, GHC 8.8, or even GHC 9.0!  This is very
different from the AMP, MFP or FTP which are/were subject to a swift
transition scheme with a rigid timeframe.

Old code still overriding `return` will continue to compile (if it
didn't break already for AMP/MFP/...) for as many years in GHC as
desired.

And code written against the new Haskell Report (especially when
ignoring the existence of the `return`-method) would work just fine
against GHC's `base` as well.

So there's not that much immediate breakage due to MRP specifically
after all.


Regards,
  H.V.Riedel

 [1]: http://i.imgur.com/DyPTZml.png
 [2]: http://learnyouahaskell.com/a-fistful-of-monads#the-monad-type-class


More information about the Libraries mailing list