The following
(&&) :: Bool -> Bool -> Bool
False && _ = False
True && False = False
True && True = True
has the desired short-circuit property False && undefined ≡ False
. The first clause, which is non-strict in the right argument, is guaranteed to be checked before anything else is tried.
Apparently, it still works if I change the order and even uncurry the function
both :: (Bool,Bool) -> Bool
both (True,False) = False
both (True, True) = True
both (False, _) = False
Prelude> both (False, undefined)
False
but is this actually guaranteed by the standard? Unlike with the order of clauses, the order of evaluation of the patterns is not so clear here. Can I actually be sure that matching (True,False)
will be aborted as soon as (False,_)
is determined, before the snd element is evaluated at all?