Short circuiting (&&) in Haskell

4.8k Views Asked by At

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

For example

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?

4

There are 4 best solutions below

5
On BEST ANSWER

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.

0
On

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

0
On

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

1
On

A simple test to "prove" that Haskell DO have short circuit, as Caleb said.

If you try to run summation on an infinite list, you will get stack overflow:

Prelude> foldr (+) 0 $ repeat 0
*** Exception: stack overflow

But if you run e.g. (||) (logical OR) on in infinite list, you will get a result, soon, because of short circuiting:

Prelude> foldr (||) False $ repeat True
True