Skip to content

Instantly share code, notes, and snippets.

@davidgrenier
Created February 5, 2014 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidgrenier/8834913 to your computer and use it in GitHub Desktop.
Save davidgrenier/8834913 to your computer and use it in GitHub Desktop.
Extensible Pattern Matching
//Hi Julie, I liked your article and couldn't resist offering some possible improvements. I don't know
//what all the formulae mean but F#'s pattern matching is pretty powerful but also extensible and can
//be used to greatly improve readability and your chances of getting the code right in the first go.
//
//Below you can see the definition of two Active Pattern to extend F#'s pattern matching with a way
//to extract information from simple values, in this case floats.
let (|GreaterThan|_|) num = function
| value when value > num -> Some ()
| _ -> None
let (|LesserThan|_|) num = function
| value when value < num -> Some ()
| _ -> None
//You can then apply it in pattern matching position to express your tolerance formula this way:
let tolerance2 = function
| Some (GreaterThan 1.94 | LesserThan 1.) -> 1.
| _ -> 0.979
//You can see pattern matching can be nested inside other pattern matches, also supporting alternation
//constructs and alleviating all needs for type annotation. The handy 'function' shortcut makes for a nice
//substitute in case of the form ``let f x = match x with ...``.
//I had little doubts when I implemented my pattern matching but decided to import FsCheck and make sure it
//behaved just like your original function:
#r @"C:\Projects\Lib\FsCheck.dll"
FsCheck.Check.Quick("Tolerance", fun x -> tolerance x = tolerance2 x)
//Gave the following result: Tolerance-Ok, passed 100 tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment