Pattern matching in F#

Pattern matching allows us to use a more powerful form of if..then..else or switch/select case type statements.

We declare a pattern matching implementation as follows

let option o =
   match o with
   | 1 -> "item 1"
   | 2 -> "item 2"
   | _ -> "unkown"

// usage
let choice = option 2

The _ is used as a wildcard character, i.e. anything not matching the patterns above..

We can also add matching along the lines of

let option o =
   match o with
   | o when o <= 0 -> failwith "value must be greater than 0"
   // other patterns

You can also match to more than one pattern as per

let option o =
   match o with
   | 1 | 2 -> "one or two"
   // other patterns

We can also pattern match on tuples for example

let options tuple =
match tuple with
   | "one", 1 -> "got one"
   | "two", 2 -> "got two"
   | _, _ -> "unknown"

// usage
let k = options ("one", 1)
printfn "%s" <| k 

Better still we can ignore part of a tuple

 let options tuple =  match tuple with    | "one", _ -> "got one"
   | _, 2 -> "got two"
   | _, _ -> "unknown"

// usage
let k = options ("?", 2)
printfn "%s" <| k 

or we could use the following to denote tuples

 let options (a, b) =     match (a, b) with    | "one", _ -> "got one"
   | _, 2 -> "got two"
   | _, _ -> "unknown"

let k = options ("?", 2)
printfn "%s" <| k

Type pattern matching

We can also use the pattern matching to match against the type of the value passed to it, for example

<![CDATA[
let value = 3.12f

let y =
   match box value with
   | :? System.Int32 -> "integer"
   | :? System.Single -> "float"
   | :? System.String -> "string"
   | _ -> "undefined"

printfn "%s" <| y
]]>

In the above we need to use box, alternatively we can use the following

let y (o: obj) =
   match o with
   | :? System.Int32 -> "integer"
   | :? System.Single -> "float"
   | :? System.String -> "string"
   | _ -> "undefined"

printfn "%s" <| string y

Note: Here, instead of creating a let statement to get the result from the match I’m supplying it directly to the printfn function. Interestingly whilst the return is a string and the printfn I set to output a string, at this point it’s a generic string and we need to cast it directly to a string (non-generic)