In GHC.Base
the description of <**>
runs:
A variant of
<*>
with the arguments reversed.
It is widely known that "reversed" in that case does not mean "flipped" as:
GHCi> [1, 2, 3] <**> [(^2), (+1)]
[1,2,4,3,9,4]
GHCi> [(^2), (+1)] <*> [1, 2, 3]
[1,4,9,2,3,4]
So, what does "reversed" mean?
Side note: there are applicative functors which have (<**>) = flip (<*>)
. For example, here is my proof for the reader ((->) e
):
(->) e: f <**> g =
= liftA2 (flip ($)) f g =
= (flip ($) <$> f) <*> g =
= \e -> ((flip ($) . f) e) (g e) =
= \e -> flip ($) (f e) $ (g e) =
= \e -> (g e) $ (f e) =
= \e -> g e (f e) =
= g <*> f. => (<**>) = flip (<*>).
I recently added do
-notation to the base documentation which makes it easier to compare <*>
and <**>
, notice how both of them run left-to-right and both of them return f a
:
fs <*> as
=
do f <- fs
a <- as
pure (f a)
and
as <**> fs
=
do a <- as
f <- fs
pure (f a)
It is known and codified (Control.Applicative.Backwards
) that applicatives can be run backwards , I have to cut this answer short. Li-yao Xia's answer with liftA2 ($) and liftA2 (&)