From bf6dbe3d1046573cb71fd534a326a9a0e6f1b220 Mon Sep 17 00:00:00 2001
From: Chris Martin
Date: Wed, 27 Mar 2019 14:23:57 -0600
Subject: [PATCH] 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 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs
index cf9fd81..a992368 100644
--- a/libraries/base/GHC/Base.hs
+++ b/libraries/base/GHC/Base.hs
@@ -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:
--
1.9.1