Records in F#

A far more comprehensive and frankly much better post on the subject of records can be found here.

However this post is an attempt to distil things down to some of the basics.

Declaring a record type

Records can be thought of as a cross between a tuple with named fields and a specialised class. Basically the syntax is more in keeping with a class type but the specialisations are that, all properties are automatically exposed, you cannot define constructors as per classes and they have structural equality semantics as opposed to a classes reference equality semantics.

Let’s declare a record type

type Person = { Name : string; Age : int }

Now to use this we simple write the following

let p = { Name = "Bob"; Age = 43 }

So as you see we do not need to actually use the type name Person in the declaration (hence it appears similar to a tuple but with named properties and ofcourse using {…} instead of (…)).

What if we declared the following

type Person = { Name : string; Age : int }
type Employee = { Name : string; Age : int }

let p = { Name = "Bob"; Age = 43 }

What type is p ?

The value p will actually be assigned the type Employee as this was the last record declared. So we need a way to explicitly declare the type we want p to be (in the example above). This is done in the following way

let p = { Person.Name = "Bob"; Age = 43 }

Now p is of type Person.

You will need to assign each of the named properties when creating a value of a record.

To access the properties, we simply use dot notation and the property name, thus

let p = { Person.Name = "Bob"; Age = 43 }

let n = p.Name

Deconstructing a record

We can also deconstruct a record to it’s constituent value as follows

let p = { Person.Name = "Bob"; Age = 43 }

let { Name = n; Age = a } = p

The above let looks slightly odd in that we appear to be assigning the value n to Name whereas it’s actually the other way around in essence.

Again, if you have more than one type which looks the same (as Person and Employee) you can again prefix the deconstruction to ensure the type is matched for example

let { Person.Name = n; Age = a } = p