I think you are mistaken, if I understood right one of the key properties of monads is to ensure order of execution, therefore if you do:

r1 <- m1
r2 <- m2

you are going to run both m1 and m2 (and in this order).

and indeed:

---------
import Control.Monad

(<||>) = liftM2 (||)

f1 = do
    putStrLn "f1"
    return True

f2 = do
    putStrLn "f2"
    return True

main = do f1 <||> f2
---------

output is:

f1
f2


On Sat, Nov 3, 2012 at 9:37 AM, Rustom Mody <rustompmody@gmail.com> wrote:
On Wed, Oct 31, 2012 at 10:44 PM, Daniel Trstenjak <daniel.trstenjak@gmail.com> wrote:

(<||>) :: Monad m => m Bool -> m Bool -> m Bool
(<||>) m1 m2 = do
   r1 <- m1
   if r1 then return True else m2


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
--
http://blog.languager.org



_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners