views:

119

answers:

3

Hi

A quick question that has been bugging me lately. Does Haskell perform all the equivalence test in a function that returns a booleanm, even if one returns a false value? eg:

f a b = ((a+b) == 2) && ((a*b) == 2)

If the first test returns false, will it perform the second test after the &&? Or is Haskell lazy enough to not do it and move on?

+7  A: 

Should be short circuited just like other languages. It's defined like this in the Prelude:

(&&)                    :: Bool -> Bool -> Bool
True  && x              =  x
False && _              =  False

So if the first parameter is False the 2nd never needs to be evaluated.

Caleb
Is this also the same in the case of list comprehensions?
Jonno_FTW
`Short circuit` is not spoken correctly. You simply don't know whether the values are evaluated since you have no way to prove it without side effects, but it's unlikely that they will unless needed.
Dario
I think it's the same as C++: the language says the right-hand side doesn't get evaluated. But of course if the compiler can tell there aren't any side effects, it may evaluate it anyway--and some C++ compilers do so, since conditional branches are expensive.
Jason Orendorff
Note that evaluating thunks in Haskell *can* have side effects: errors or infinite loops. So just like C++, the compiler has to check for possible side effects first, if it wants to evaluate something it's technically not supposed to.
Jason Orendorff
Caleb
+2  A: 

Lazy evaluation means, that nothing is evaluated till it is really needed.

Martin Kopta
+2  A: 

Like Martin said, languages with lazy evaluation never evaluate anything that's value is not immediately needed. In a lazy language like Haskell, you get short circuiting for free. In most languages, the || and && and similar operators must be built specially into the language in order for them to short circuit evaluation. However, in Haskell, lazy evaluation makes this unnecessary. You could define a function that short circuits yourself even:

scircuit fb sb = if fb then fb else sb

This function will behave just like the logical 'or' operator. Here is how || is defined in Haskell:

True  || _ = True
False || x = x

So, to give you the specific answer to your question, no. If the left hand side of the || is true, the right hand side is never evaluated. You can put two and two together for the other operators that 'short circuit'.

Rayne