Let's start with the obvious fact: such a definition for <*>
violates the ap
-law in the sense that <*>
should ap
, where ap
is the one defined in the Monad
class, i.e. the first one you posted.
Trivialities aside, as far as I can see, the other applicative laws should hold.
More concretely, let's focus on the composition law you mentioned.
Your "reversed" ap
(<**>) m1 m2 = do { x <- m2 ; f <- m1 ; return (f x) }
can also be defined as
(<**>) m1 m2 = pure (flip ($)) <*> m2 <*> m1
where <*>
is the "regular" ap
.
This means that, for instance,
u <**> (v <**> w) =
{ def. <**> }
pure (flip ($)) <*> (v <**> w) <*> u =
{ def. <**> }
pure (flip ($)) <*> (pure (flip ($)) <*> w <*> v) <*> u =
{ composition law }
pure (.) <*> pure (flip ($)) <*> (pure (flip ($)) <*> w) <*> v <*> u =
{ homomorphism law }
pure ((.) (flip ($))) <*> (pure (flip ($)) <*> w) <*> v <*> u =
{ composition law }
pure (.) <*> pure ((.) (flip ($))) <*> pure (flip ($)) <*> w <*> v <*> u =
{ homomorphism law (x2)}
pure ((.) ((.) (flip ($))) (flip ($))) <*> w <*> v <*> u =
{ beta reduction (several) }
pure (\x f g -> g (f x)) <*> w <*> v <*> u
(I hope I got everything OK)
Try doing something similar to the left hand side.
pure (.) <**> u <**> v <**> w = ...