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

Herbert Valerio Riedel hvr at gnu.org
Sun Oct 4 09:35:45 UTC 2015


Hello,

On 2015-10-03 at 16:43:53 +0200, Andrés Sicard-Ramírez wrote:
> In Agda, we added support for GHC 7.10.* following the migration guide
> available at
>
>   https://ghc.haskell.org/trac/ghc/wiki/Migration/7.10
>
> In particular, we added instances of Applicative using
>
>   instance Applicative Foo where
>     pure  = return
>     (<*>) = ap  -- defined in Control.Monad
>
>
> After reading the "Monad of no `return` proposal" below, I have two questions:
>
> 1. Shouldn't the above migration guide to be changed to something like
>
>   instance Applicative Foo where
>     pure  = <copy-the-definition-of-return>
>     ...
>
>   instance Monad Foo where
>     return = pure
>
> ?

Indeed, I've updated the GHC wiki page accordingly, thanks for pointing
that out!

> 2. Since in Agda code `return` is used everywhere, does follow (1) has
> some performance cost?

If you have generic code which doesn't get specialised to a specific
class dictionary for Monad/Applicative then there's the overhead of an
additional indirection (depending on which way around the
Monad/Applicative instances were defined).

The AMP instructions were formulated in a way to make manual refactoring
easiest, while they don't necessarily match how you'd define instances
from scratch in a post-AMP setting.

Given the convenience of the post-AMP default-method-implementation of
`return`, I expect new code to start defining `return` in terms of
`pure` rather than the other way around, and older existing code will
probably slowly migrate to that state as well.

Given the usual 3-major-GHC-version compatibility window convention we
strive for in Hackage-released Haskell code, starting with GHC 8.2, code
written not defining `return` explicitly anymore will be compliant with
this convention.

In any case, if you *know* that you incur an overhead if you use
`return` rather than `pure` in your code (due to
e.g. non-specialisation) and don't want to refactor your code just yet
to use `pure` instead of `return`, you can hide the import of `return`
and define an inlineable `return = pure` top-level binding in its
place. Otoh, if you have code which doesn't specialise the
Monad-instances I'd expect the `return`-induced overhead to be a minor
contribution as GHC will have already missed a few other opportunities
to inline and optimise your code.

Cheers,
  hvr


More information about the Libraries mailing list