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