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?
There are always several ways to implement the same thing. The advantage of pattern matching is that it is very flexible and powerful at the same time. Within the pattern, the data structure can be dynamically disassembled. These parts can then be assigned directly to variables that only apply within this expression.
What Does Pattern Matching Mean? Pattern matching in computer science is the checking and locating of specific sequences of data of some pattern among raw data or a sequence of tokens. Unlike pattern recognition, the match has to be exact in the case of pattern matching.
Pattern matching is used to determine whether source files of high-level languages are syntactically correct. It is also used to find and replace a matching pattern in a text or code with another text/code. Any application that supports search functionality uses pattern matching in one way or another.
The Importance of Pattern Recognition Pattern finding is the essence of wisdom since patterns embody structure and order, which helps organize our work, making it more accessible. Finding and understanding patterns is a crucial element of problem-solving and mathematical thinking.
Yes, it is guaranteed that evaluating the expression both (False, undefined)
will not diverge since matching on data constructors is guaranteed to match left-to-right against the components of the constructor and the pattern fails as soon as some sub-pattern fails. Since the first element of the tuple is False
, the pattern will fail for both (True, ...)
branches as soon as the first element fails to match.
Per the Haskell 2010 Report, section 3.17.2, which gives an informal semantics of pattern matching:
- Matching the pattern con pat1 … patn against a value, where con is a constructor defined by data, depends on the value:
- If the value is of the form con v1 … vn, sub-patterns are matched left-to-right against the components of the data value; if all matches succeed, the overall match succeeds; the first to fail or diverge causes the overall match to fail or diverge, respectively.
- If the value is of the form con′ v1 … vm, where con is a different constructor to con′, the match fails.
- If the value is ⊥, the match diverges.
Since the tuple syntax is just a special-case syntactic sugar for a data constructor, the above applies.
For a fuller treatment of pattern matching, see section 3.17.3 of the Haskell 2010 Report, which gives a formal semantics of pattern matching (specifically, figure 3.2 pertains to this question).
Another resource of interest is the paper Pattern-driven Reduction in Haskell which specifies the semantics as an interpreter (written in Haskell) of an abstract syntax representation of Haskell's concrete syntax (the function mP
in figure 3, page 7 is relevant to the question).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With