Inline the definition of 'ap' in the Monad laws
authorChris Martin <ch.martin@gmail.com>
Wed, 27 Mar 2019 20:23:57 +0000 (14:23 -0600)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 3 Apr 2019 04:41:05 +0000 (00:41 -0400)
commitbf6dbe3d1046573cb71fd534a326a9a0e6f1b220
tree28e31e50b3b524ada9934ec861f068027dbfcf8f
parent722fdddf31932236d4246821cb79987fa9422a7e
Inline the definition of 'ap' in the Monad laws

The law as it is currently written is meaningless, because nowhere have
we defined the implementation of 'ap'. The reader of the Control.Monad
documentation is provided with only a type signature,

> ap :: Monad m => m (a -> b) -> m a -> m b

an informal description,

> In many situations, the liftM operations can be replaced by uses of
> ap, which promotes function application.

and a relationship between 'ap' and the 'liftM' functions

> return f `ap` x1 `ap` ... `ap` xn
> is equivalent to
> liftMn f x1 x2 ... xn

Without knowing how 'ap' is defined, a law involving 'ap' cannot
provide any guidance for how to write a lawful Monad instance, nor can
we conclude anything from the law.

I suspect that a reader equipped with the understanding that 'ap' was
defined prior to the invention of the Applicative class could deduce
that 'ap' must be defined in terms of (>>=), but nowhere as far as I can
tell have we written this down explicitly for readers without the
benefit of historical context.

If the law is meant to express a relationship among (<*>), (>>=), and
'return', it seems that it is better off making this statement directly,
sidestepping 'ap' altogether.
libraries/base/GHC/Base.hs