Pattern matching snippets
#light
open System
// *************************************************************
// * Pattern matching using match/with
// *************************************************************
// This is not legal, since DateTime.Today is a variable...
let dayDescriptor1 (day : DateTime) =
match day with
| DateTime.Today -> "today"
| _ -> "not today"
// This is however, since the 'when guard' can be an expression
let dayDescriptor2 (day : DateTime) =
match day with
| _ when day = DateTime.Today -> "today"
| _ -> "not today"
// *************************************************************
// * Pattern matching using functions
// *************************************************************
// The 'function' keyword is similar to 'fun', except that it
// only produces functions which take a single parameter and
// that parameter is treated as if it were put into a
// match/with block.
// For example, this function returns true IFF the tuple parameter
// is ("Chris", "Smith")
let isMe = function "Chris", "Smith" -> true
| _, _ -> false
assert (isMe ("Bill", "Gates") = false)
// *************************************************************
// * Basic pattern matching using let bindings
// *************************************************************
// Assign two variables at once
let today, tomorrow = DateTime.Now, DateTime.Now.AddDays(1.0)
// Declare a list of elements, note that tail has value [4..100]
let a :: b :: c :: tail = [1..100]
// *************************************************************
// * Advanced pattern matching using let bindings
// *************************************************************
// Let's say you have a discriminated union...
type Foo = A of int | B of string * int
// You can use a pattern on the let binding to suck out the
// value from your discriminated union. This _greatly_
// cleans up code since you don't need a million
// match/with blocks.
let value = B("ZG", 7)
let A(x) | B(_, x) = value
assert (x = 7)
// You can use the same technique on records too...
type Party = Dem | Rep | Ind | Green | Other of string
type PresidentialCandidate = {Name : string; Party : Party}
let getCandidateName {Name = name ; Party = _ } = name
// Other ways to write the same method:
let getCandidateName2 = function {Name = name; Party = _} -> name
let getCandidateName3 candidate =
match candidate with
{Name = name; Party = _} -> name
// *************************************************************
// * The downside :(
// *************************************************************
// The following is legal code, but results in a runtime exception.
// I'll leave it as an exercise to the reader why this is allowed.
let 1 = 2