is the evaluation order deterministic when using applicative with IO

Hi everyone. I was wondering if I can make assumptions about the evaluation order of the following code: isTrue :: Int -> IO Bool isTrue val = pure (||) <*> boolTest1 val <*> boolTest2 val {- boolTest1 is an inexpensive, quick check -} boolTest1 :: Int -> IO Bool boolTest1 val = undefined {- boolTest2 is a very expensive check -} boolTest2 :: Int -> IO Bool boolTest2 val = undefined When using Applicative in the isTrue function, I would like to make use of the short-circuit behaviour of || and rely on the fact that the boolTest1 will be executed first. The reason I am asking is because the boolTest functions are in the IO monad, instead of just returning pure Bool values. Regards Rouan.

On 16/03/12 10:45, Rouan van Dalen wrote:
Hi everyone.
I was wondering if I can make assumptions about the evaluation order of the following code:
isTrue :: Int -> IO Bool isTrue val = pure (||) <*> boolTest1 val <*> boolTest2 val
{- boolTest1 is an inexpensive, quick check -} boolTest1 :: Int -> IO Bool boolTest1 val = undefined
{- boolTest2 is a very expensive check -} boolTest2 :: Int -> IO Bool boolTest2 val = undefined
When using Applicative in the isTruefunction, I would like to make use of the short-circuit behaviour of || and rely on the fact that the boolTest1 will be executed first. The reason I am asking is because the boolTest functions are in the IO monad, instead of just returning pure Bool values.
The evaluation order is always from left to right with the instance Applicative IO. However, both sides will still be evaluated. isTrue is equivalent to: isTrue val = do t1 <- boolTest1 val t2 <- boolTest2 val return (t1 || t2) If you want to avoid the side effects of boolTest2 when boolTest1 returns true, you will need to implement a monadic or, something like orM ma mb = do a <- ma if a then return True else mb Twan

On Fri, Mar 16, 2012 at 12:30:13PM +0100, Twan van Laarhoven wrote:
If you want to avoid the side effects of boolTest2 when boolTest1 returns true, you will need to implement a monadic or, something like
orM ma mb = do a <- ma if a then return True else mb
Note also that it is *not possible* to have this short-circuiting behavior using only Applicative. The structure of an Applicative computation is always fixed up front, and cannot depend on intermediate values. -Brent

As usual you can check:
Prelude Control.Applicative> pure (||) <*> pure True <*> undefined
*** Exception: Prelude.undefined
Prelude Control.Applicative> (||) True undefined
True
2012/3/16 Rouan van Dalen
Hi everyone.
I was wondering if I can make assumptions about the evaluation order of the following code:
isTrue :: Int -> IO Bool isTrue val = pure (||) <*> boolTest1 val <*> boolTest2 val
{- boolTest1 is an inexpensive, quick check -} boolTest1 :: Int -> IO Bool boolTest1 val = undefined
{- boolTest2 is a very expensive check -} boolTest2 :: Int -> IO Bool boolTest2 val = undefined
When using Applicative in the isTrue function, I would like to make use of the short-circuit behaviour of || and rely on the fact that the boolTest1 will be executed first. The reason I am asking is because the boolTest functions are in the IO monad, instead of just returning pure Bool values.
Regards Rouan.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Rouan van Dalen
I was wondering if I can make assumptions about the evaluation order of the following code:
Nitpick: This is execution order, not evaluation order. The evaluation order is indeed undefined here. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/
participants (5)
-
Brent Yorgey
-
Dmitry Olshansky
-
Ertugrul Söylemez
-
Rouan van Dalen
-
Twan van Laarhoven