F#7 : Records

So we continue our journey into more of the F# types. This time we will be looking at Record types.

 

How Do I Create A Record

When you create a new F# record, it may remind you of anonymous objects in C#. Here is how you create them. I think they are quite similar to anonymous objects in C#, so if you have used C#, F#s records should not be that hard to get into.

It starts by creating a new type for the record. The type definition lists the name of the properties and also the type of the properties, this can be seen below.

Once you have a record type definition you re free to bind a new instance to a value use Let. Again an example of this can be seen below, where we bind a new record using a Let binding, and we also print the property values of the record instance to the console output.

type Person = { Age : int; Sex: string; Name:string; }  
....
....
....
....
let sam = { Age = 12; Sex="Male"; Name ="Sam" }
printfn "let sam = { Age = 12; Sex=\"Male\"; Name=\"Sam\" }" 
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.Name

which gives this result

image

 

How Do I Alter/Clone A Record

You are able to clone and alter a record, which is typical done as follows:

//clone and alter sam to become new Person tom
let sam = { Age = 12; Sex="Male"; Name ="Sam" }
let tom = { sam with Name="Tom" }
printfn "let tom = { sam with Name=\"Tom\" }" 
printfn "Person with Age is %i and Sex is %s and Name is %s" tom.Age tom.Sex tom.Name

Which gives this result

image

Note how we used the “with” keyword when creating the new tom person instance. This form of the record expression is called the “copy and update record expression”. Another choice you could use (again we will be covering this in more detail in a later post) is use a mutable property in your record type. Records are immutable by default; however, you can also explicitly specify a mutable field.

Here is an example, notice how I have created a new type which has a mutable property called MutableName. By defining a mutable field, I am allowed to update the value of the MutableName property of the record, which you can do using the “<-“ operator. Which simply allows a new value to be assigned.

type MutableNamePerson = { Age : int; Sex: string; mutable MutableName:string; }   
....
....
....
....
//create
let sam = { Age = 12; Sex="Male"; MutableName ="Sam" }
printfn "let sam = { Age = 12; Sex=\"Male\"; Name=\"Sam\" }" 
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.MutableName
//update
sam.MutableName <- "Name changed"
printfn "sam.MutableName <- \"Name changed\"" 
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.MutableName
    

Which has this result

image

 

 

Record Equality

Record types are only equal if ALL the properties are considered the same. Here is an example

type Person = { Age : int; Sex: string; Name:string; }   
....
....
....
....
let someFunction p1 p2 =
    printfn "p1=%A, and p2=%A, are they equal %b" p1 p2 (p1=p2)


let sam =  { Age = 12; Sex = "Male"; Name = "Sam" }
let john = { Age = 12; Sex = "Male"; Name = "John" }
let april = { Age = 35; Sex = "Female"; Name = "April" }
let sam2 = { Age = 12; Sex = "Male"; Name = "Sam" }
do someFunction sam john
do someFunction sam april
do someFunction sam sam2

And here is the result

image

Pattern Matching Records

It is of course possible to use pattern matching (a discussion for another day),  which is a core F# technique, to match against Record types. Here is an example

type Person = { Age : int; Sex: string; Name:string; }  
.....
.....
.....
.....
let someFunction (somePerson :Person) =
    match somePerson with
    | { Name="Sam" }    -> printfn "Sam is in the house"
    | _                 -> printfn "you aint Sam, get outta here clown"


let sam = { Age = 12; Sex="Male"; Name ="Sam" }
let john = { Age = 12; Sex="Male"; Name ="John" }
do someFunction sam
do someFunction john

Which has the result

image

Methods And Properties

It is also possible to add extra members to records. Here is an example where we add a “Details” property to allow the full details of the record to be obtained by using a single property (much as the we could achieve by overriding the ToString() method, but more on OO techniques later on ok)

Note that if you tried to add a member to the record type definition as shown in this screen shot you will get a strange error

image

This is easily solved by simply putting the record property definitions on a new line, and making sure the member starts on a new line too, and watch that indenting (whitespace), as it is all important in F#

type Person = 
    { Age : int; Sex: string; Name:string; }   
    member this.Details = this.Age.ToString() + " " + this.Sex.ToString() + " " + this.Name
....
....
....
....
let sam =  { Age = 12; Sex = "Male"; Name = "Sam" }
printfn "sam Details=%s" sam.Details

 

Which has the result

image

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: