
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