« Many worlds | Main | Report on planet three »

July 24, 2010

F# pattern matching for beginners, part 5: more useful patterns

In this part, I want to briefly mention some useful patterns that I haven’t covered in the previous instalments.  I’m not going to cover everything, but if you want to know more, the F# documentation contains a full list of patterns with examples.

Record patterns

In addition to tuples, F# supports record types, which have named members like C# or Visual Basic classes.  A record pattern is like a tuple pattern, but identifies members by name instead of by position.  It uses curly brace syntax, with semicolon separators if multiple fields are involved in the pattern.

type Person = {
  Name : string;
  Age : int

let isBob person =
  match person with
  | { Person.Name = "bob" } -> true
  | _ -> false
> isBob { Name = "bob"; Age = 40 };; 
val it : bool = true 
> isBob { Name = "alice"; Age = 50 };; 
val it : bool = false

Obviously, you’re not restricted to a constant expression: you can use a variable expression to capture the decomposed values:

let getAgeIfBob person =
  match person with
  | { Person.Name = "bob"; Person.Age = age } -> Some age
  | _ -> None

Type testing

A type test pattern is like the C# is operator: it matches if the matched item is an instance of the specified type.  Its syntax is :? followed by the type name.  The result of a successful match is strongly-typed to the specified type, and you can use an as pattern to capture this strongly-typed value into a variable so you can access type-specific members.

let sizeof (obj : Object) =
  match obj with
  | :? int -> Some 4
  | :? string as s -> Some s.Length
  | _ -> None
> sizeof 123;; 
val it : int option = Some 4 
> sizeof "hibble bibble";; 
val it : int option = Some 13 
> sizeof DateTime.Now;; 
val it : int option = None

Note we could not have called Length on obj directly, because the F# compiler would complain that Object doesn’t have a Length property.  Hence the need to capture the result of the :? string pattern: the F# compiler knows that this is of type string, so it is safe to access the Length property.

Other patterns

For other patterns defined by F#, see the Patterns topic in the documentation.

But what if you have classification and decomposition logic that can’t be readily expressed using the compiler-defined patterns?  In the final part of this series, we’ll look at how you can extend the F# pattern system with your own active patterns.

July 24, 2010 in Software | Permalink


TrackBack URL for this entry:

Listed below are links to weblogs that reference F# pattern matching for beginners, part 5: more useful patterns: