Commit bf6dbe3d authored by Chris Martin's avatar Chris Martin Committed by Marge Bot

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.
parent 722fdddf
......@@ -519,7 +519,7 @@ class Functor f where
-- * @'pure' = 'return'@
-- * @('<*>') = 'ap'@
-- * @m1 '<*>' m2 = m1 '>>=' (\x1 -> m2 '>>=' (\x2 -> 'return' (x1 x2)))@
-- * @('*>') = ('>>')@
......@@ -639,7 +639,7 @@ Instances of 'Monad' should satisfy the following:
Furthermore, the 'Monad' and 'Applicative' operations should relate as follows:
* @'pure' = 'return'@
* @('<*>') = 'ap'@
* @m1 '<*>' m2 = m1 '>>=' (\x1 -> m2 '>>=' (\x2 -> 'return' (x1 x2)))@
The above laws imply:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment