Patterns

Definition

Patterns are rules for detecting input data structure.

Used extensively in Fβ™―

  • match expression, let binding, parameter deconstruction...

  • Very practical for manipulating Fβ™― algebraic types (tuple, record, union)

  • Composable: supports multiple nesting levels

  • Combined using logical AND/OR

  • Supports literals: 1.0, "test"...

Wildcard Pattern

Represented by _, alone or combined with another pattern.

Always true β†’ To be placed last in a match expression.

⚠️ Always seek 1st to handle all cases exhaustively/explicitly When impossible, then use _

match option with
| Some 1 -> ...
| _ -> ...              // ⚠️ Non exhaustive

match option with
| Some 1 -> ...
| Some _ | None -> ...  // πŸ‘Œ More exhaustive

Recommendation

Constant Pattern

Detects constants, null and number literals, char, string, enum.

☝ Notes :

  • The Three pattern is also classified as an Identifier Pattern πŸ“

  • For null matching, we also talk about Null Pattern.

Variable Pattern

Assigns the detected value to a "variable" for subsequent use

Example: b variable below

⚠️ You cannot link to the same variable more than once.

πŸ’‘ Solution: use 2 variables then check their equality

Identifier Pattern

Detects cases of a union type and their possible contents

The identifier pattern can be combined with both constant and variable patterns. When the cases fields have labels, we can pattern match on them too:

OR / AND Patterns

Combine two patterns (named P1 and P2 below):

  • P1 | P2 β†’ P1 or P2 - E.g. Rectangle (0, _) | Rectangle (_, 0)

  • P1 & P2 β†’ P1 and P2 - used especially with active patterns πŸ“

☝️ Explanations:

  • The Title is optional. The first pattern { Title = Some name } will match only if the Title is specified.

  • The second pattern { Filename = name } will always works. It's written to extract the Filename into the same variable name as the first pattern.

Warning

Alias Pattern

as is used to name an element whose content is deconstructed

πŸ’‘ Also works within functions to get back the parameter name, person below:

πŸ’‘ The AND pattern can be used as an alternative to the alias pattern. ☝️ However, it won't work to get the parameter name:

Parenthesized Pattern

Purpose: Use of parentheses () to group patterns

Common use case: tackle precedence

☝ Line β‘  would compile without doing () :: tail ⚠️ Parentheses complicate reading πŸ’‘ Try to do without when possible:

Construction Patterns

Use type construction syntax to deconstruct a type

  • Cons and List Patterns

  • Array Pattern

  • Tuple Pattern

  • Record Pattern

Cons and List Patterns

≃ Inverses of the 2 ways to construct a list

Cons Pattern : head :: tail β†’ decomposes a list (with >= 1 element) into:

  • Head: 1st element

  • Tail: another list with the remaining elements - can be empty

List Pattern : [items] β†’ decomposes a list into 0..N items

  • [] : empty list

  • [x] : list with 1 element set in the x variable

  • [x; y] : list with 2 elements set in variables x and y

  • [_; _]: list with 2 elements ignored

πŸ’‘ x :: [] ≑ [x], x :: y :: [] ≑ [x; y]...

The default match expression combines the 2 patterns: β†’ A list is either empty [], or composed of an item and the rest: head :: tail

Example: β†’ Recursive functions traversing a list β†’ The [] pattern is used to stop recursion:

Array Pattern

Syntax: [| items |] for 0..N items between ;

☝ There is no pattern for sequences, as they are "lazy ".

Tuple Pattern

Syntax: items or (items) for 2..N items between ,.

πŸ’‘ Useful to match several values at the same time

Record Pattern

Syntax: { Field1 = var1; ... }

  • It's not required to specify all fields in the record

  • In case of ambiguity on the record type, qualify the field: Record.Field

πŸ’‘ Also works for function parameters:

⚠️ Reminder: there is no pattern for anonymous Records!

Type Test Pattern

Syntax: my-object :? sub-type and returns a bool β†’ ≃ my-object is sub-type in Cβ™―

Usage: with a type hierarchy

☝️ Note: the :? operator is not designed to check evidence, which can be confusing. β†’ Example: (from stackoverflow)

try/with block

This pattern is common in try/with blocks:

Boxing

The Type Test Pattern only works with reference types. β†’ For a value type or unknown type, it must be boxed.

Last updated

Was this helpful?