Emmanuel Touzery etouzery at gmail.com
Sat Nov 3 12:02:52 CET 2012

```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:

---------

(<||>) = 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 at gmail.com> wrote:

> On Wed, Oct 31, 2012 at 10:44 PM, Daniel Trstenjak <
> daniel.trstenjak at 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
>
> 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