diff options
author | Chris Martin <ch.martin@gmail.com> | 2019-03-27 14:23:57 -0600 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-04-03 00:41:05 -0400 |
commit | bf6dbe3d1046573cb71fd534a326a9a0e6f1b220 (patch) | |
tree | 28e31e50b3b524ada9934ec861f068027dbfcf8f | |
parent | 722fdddf31932236d4246821cb79987fa9422a7e (diff) | |
download | haskell-bf6dbe3d1046573cb71fd534a326a9a0e6f1b220.tar.gz |
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.
-rw-r--r-- | libraries/base/GHC/Base.hs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs index cf9fd81c70..a9923681f4 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: |