Pattern Matching
Felix provides 3 kinds of pattern matching: algebraic pattern matching,
regular sequence matching and general LR parsing. This section only
deals with algebraic pattern matching. Just as certain expressions
terms are used to compose or construct
new values, such as infix ,
for tuples, so pattern matching is the dual operation, and is used to
untangle or destroy a value.
Note the term destructor implies finding the component parts of a
value, not actually destroying it, so the meaning is different to C++.
Algebraic Pattern Matching
Algebraic pattern matching matches the term structure of a value's type
against a pattern for that type, resulting in the binding of pattern
variables to subterms of the term. All of the following kinds of
pattern matching can be combined arbitrarily. All algebraic pattern
matches work with the base expression syntax:
match
<m-expr> with
| <pattern1> =>
<r1-expr>
...
endmatch
The components of a pattern are:
Pattern
|
Meaning
|
literal
|
Matches its value, can be an
integer, float or string
|
literal .. literal
|
Matches a value in the denoted
range inclusively
|
_
|
Matches anything
|
?ident
|
Matches anything and binds
variable ident to it
|
name pattern
|
Matches union constructor name
|
| case i pattern |
Matches the i'th component of a
sum |
pattern,pattern,..
|
Matches tuples
|
| pattern when cond |
Matches the pattern provided the
condition is met, the condition may depend on pattern variables |
pattern as name
|
Matches the pattern and binds
name to it
|
pattern : type
|
pattern with a type annotation
|
Each pattern of match is considered in order, if a match is found the
associated expression is the value of the match expression, with any
occurenced of pattern variables replaced by the values bound to them.
If none of the match cases matches the expression the result is
undefined. The current implementation generates an assert() to catch this error,
which will be elided if the code is compiled with -DNDEBUG as usual.
Examples:
match 1,2,(3,4)
with
| x?,_,(?a,?b) => x + a + b
endmatch
match Some "Hello" with
| None => ""
| Some ?x => x
endmatch
match 42 with
| ?x when x == 42 => x+1
| _ => 0
endmatch
Let expression
A popular shorthand of a single match is the let expression:
let
pattern = value in expr
which is exactly equivalent to
match
value with | pattern => expr endmatch
however, let if a low precedence prefix operator, so the bindings
introduced remain in effect until the end of the expression.
Conditional expression
Another popular shorthand is the conditional expression:
if
cond then et else ef endif
which is exactly equivalent to
match
cond1 with
| case 1 => et // case 1
is true
| case 0 => ef // case 0
is false
endmatch
You can also include elif clauses in a conditional expression:
if1 cond then
e1
elif cond2 then e2
..
else e
endif
which is equivalent to a match with nested terms. Note that conditional
expressions require an else clause.