match expression provides branching control that is based on the comparison of an expression with a set of patterns.
// Match expression. match test-expression with | pattern1 [ when condition ] -> result-expression1 | pattern2 [ when condition ] -> result-expression2 | ... // Pattern matching function. function | pattern1 [ when condition ] -> result-expression1 | pattern2 [ when condition ] -> result-expression2 | ...
The pattern matching expressions allow for complex branching based on the comparison of a test expression with a set of patterns. In the
match expression, the test-expression is compared with each pattern in turn, and when a match is found, the corresponding result-expression is evaluated and the resulting value is returned as the value of the match expression.
The pattern matching function shown in the previous syntax is a lambda expression in which pattern matching is performed immediately on the argument. The pattern matching function shown in the previous syntax is equivalent to the following.
fun arg -> match arg with | pattern1 [ when condition ] -> result-expression1 | pattern2 [ when condition ] -> result-expression2 | ...
For more information about lambda expressions, see Lambda Expressions: The
The whole set of patterns should cover all the possible matches of the input variable. Frequently, you use the wildcard pattern (
_) as the last pattern to match any previously unmatched input values.
The following code illustrates some of the ways in which the
match expression is used. For a reference and examples of all the possible patterns that can be used, see Pattern Matching.
let list1 = [ 1; 5; 100; 450; 788 ] // Pattern matching by using the cons pattern and a list // pattern that tests for an empty list. let rec printList listx = match listx with | head :: tail -> printf "%d " head; printList tail |  -> printfn "" printList list1 // Pattern matching with multiple alternatives on the same line. let filter123 x = match x with | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!" | a -> printfn "%d" a // The same function written with the pattern matching // function syntax. let filterNumbers = function | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!" | a -> printfn "%d" a
Guards on patterns
You can use a
when clause to specify an additional condition that the variable must satisfy to match a pattern. Such a clause is referred to as a guard. The expression following the
when keyword is not evaluated unless a match is made to the pattern associated with that guard.
The following example illustrates the use of a guard to specify a numeric range for a variable pattern. Note that multiple conditions are combined by using Boolean operators.
let rangeTest testValue mid size = match testValue with | var1 when var1 >= mid - size/2 && var1 <= mid + size/2 -> printfn "The test value is in range." | _ -> printfn "The test value is out of range." rangeTest 10 20 5 rangeTest 10 20 10 rangeTest 10 20 40
Note that because values other than literals cannot be used in the pattern, you must use a
when clause if you have to compare some part of the input against a value. This is shown in the following code:
// This example uses patterns that have when guards. let detectValue point target = match point with | (a, b) when a = target && b = target -> printfn "Both values match target %d." target | (a, b) when a = target -> printfn "First value matched target in (%d, %d)" target b | (a, b) when b = target -> printfn "Second value matched target in (%d, %d)" a target | _ -> printfn "Neither value matches target." detectValue (0, 0) 0 detectValue (1, 0) 0 detectValue (0, 10) 0 detectValue (10, 15) 0
Note that when a union pattern is covered by a guard, the guard applies to all of the patterns, not just the last one. For example, given the following code, the guard
when a > 41 applies to both
A a and
type Union = | A of int | B of int let foo() = let test = A 42 match test with | A a | B a when a > 41 -> a // the guard applies to both patterns | _ -> 1 foo() // returns 42