We can do some algebraic simplification, using the law
if P then True else Q is same as
P || Q :
(<||>) m1 m2 = do
r1 <- m1
r2 <- m2
return (r1 || r2)
Which reminds me of the definition of liftM2
(from Control.Monad):
liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
And so we can golf down to:
(<||>) = liftM2 (||)
Now, instead of using liftM2 from Control.Monad, I could as well use liftA2 from Control.Applicative :
(<||>) = liftA2 (||)
So my questions to the experts:
1> Are these equivalent or am I missing something?
2> Any thumb rules on when to use Control.Monad and when to use Control.Applicative?
Rusi