You are previewing Programming F#.

Programming F#

Cover of Programming F# by Chris Smith Published by O'Reilly Media, Inc.
O'Reilly logo

Active Patterns

Pattern matching adds power to your programming by giving you a way to be much more expressive in code branching than using if expressions alone. It allows you to match against constants, capture values, and match against the structure of data. However, pattern matching has a significant limitation. Namely, it only has the ability to match against literal values such as string, or a limited range of class types like arrays and lists.

Ideally, pattern matching could be used to match against higher-level concepts such as elements in a seq<_>. The following is an example of what you would like to write; however, it fails to compile:

// Does not compile
let containsVowel (word : string) =
    let letters = word.Chars
    match letters with
    | ContainsAny [ 'a'; 'e'; 'i'; 'o'; 'u' ]
        -> true
    | SometimesContains [ 'y' ]
        -> true
    | _ -> false

To check if elements exist in a seq<_>, you need to resort to using when guards, which are ugly at best. The following snippet creates a Set type filled with the letters of a string, and then searches for specific letters in a pattern-match rule’s when guard:

let containsVowel (word : string) =
    let letters = word |> Set.ofSeq
    match letters with
    | _ when letters.Contains('a') || letters.Contains('e') ||
             letters.Contains('i') || letters.Contains('o') ||
             letters.Contains('u') || letters.Contains('y')
        -> true
    | _ -> false

Fortunately, in F#, there is a feature that captures all the succinct expressiveness you want with the elegance of pattern matching, ...

The best content for your career. Discover unlimited learning on demand for around $1/day.