Tracks
/
F#
F#
/
Syllabus
/
Pattern Matching
Pa

Pattern Matching in F#

1 exercise

About Pattern Matching

An if/elif/else expression can be used to conditionally execute logic. F# also has another, more powerful way to conditionally execute logic: pattern matching. With pattern matching, a value can be tested against one or more patterns. An example of such a pattern is the constant pattern, which matches a value against a constant (e.g. 1 or "hello").

In F#, pattern matching is done through the match keyword:

let describe number =
    match number with
    | 0 -> "Zero"
    | 1 -> "One"

While this may look like switch statements in other languages, pattern matching starts to shine when also using other patterns. One such pattern is the variable pattern, which allows one to capture a value:

match number with
| 0 -> "Zero"
| i -> sprintf "Non zero: %d" i

In some cases, you may want to add an additional condition to a pattern. This is known as a guard (clause), which can be added using the when keyword:

match number with
| 0 -> "Zero"
| i when i < 0 -> "Negative number"

A guard clause can be any valid expression, which includes invoking functions.

In the above example, not all possible input will have a matching pattern. The compiler will detect this and output a warning. This is known as exhaustive matching. To solve the warning, one has to handle all cases. For this, the [wildcard pattern][wildcard-pattern] can be used, which is a pattern that matches on any value:

match number with
| i when i < 0 -> "Negative number"
| _ -> "Positive number"

// No compiler warning

Note that the compiler cannot use when clauses to infer exhaustiveness:

match number with
| i when i < 0 -> "Negative number"
| i when i >= 0 -> "Positive number"

// Compiler warning

Pattern matching will test a value against each pattern from top to bottom, until it finds a matching pattern and executes the logic associated with that pattern. The order of patterns matters! Therefore, the discard pattern should always be the last pattern in a match expression.

While pattern matching is very powerful, simple conditional logic can usually be more clearly expressed using an if/else expression:

let usingPatternMatching number =
    match number with
    | 0 -> "Zero"
    | _ -> "Non-zero"

let usingIfElse number = if number = 0 then "Zero" else "Non-zero"
Edit via GitHub The link opens in a new window or tab

Learn Pattern Matching