Saturday, March 8, 2008

Records and Discriminated Unions

Like most other programming languages, it is possible with F# to create your own types when needed. Because F# is a blend of both functional languages and imperative languages, you get support for types from a functional perspecive as well as types when you have to deal with OO programming. Records Records are concrete type definitions, if you have an OO background, records will look very similar to classes. To create a record, you need to tell F# the type name, the labels and the label type. Here’s an example, using FSI
> type FamilyMember = {Name: string; relation: string};;
type FamilyMember = {Name: string; relation: string;}
There are two different ways to create record. The first way:
> {Name = "Nate";relation = "Father"};;
val it : FamilyMember = {Name = "Nate"; relation = "Father";}
Or a more explicit syntax:
> {new FamilyMember with Name = "Kelly" and relation = "Mother"};;
val it : FamilyMember = {Name = "Kelly"; relation = "Mother";}
F# makes it easy for you to access the record labels:
> let f = {new FamilyMember with Name = "Nate" and relation = "father"};;
val f : FamilyMember
> f.Name;;
val it : string = "Nate"
Records can be cloned, and like everything else with F#, it’s amazingly simple!
> let d1 = {new FamilyMember with Name = "reilly" and relation = "daughter"};;
val d1 : FamilyMember
> let d2 = {d1 with Name = "Cora"};;
val d2 : FamilyMember
> d2;;
val it : FamilyMember = {Name = "Cora";
relation = "daughter";}
Records can be results of functions as well. Take the following type, which has a count of files and a count of directories:
type FilesAndDirectorys = {Files: int; Directories: int;}
We can use it for a function like so:
let GetFilesAndDirectories loc =
let dirs = Directory.GetDirectories(loc)
let files = Directory.GetFiles(loc)
let results = {new FilesAndDirectorys with Files = files.Length and Directories = dirs.Length}
Next call the function with the path you want to search
let counts = GetFilesAndDirectories @"C:\" The identifier counts now contains the following data:

val it : FilesAndDirectorys = {Files = 9; Directories = 18;}

There is another type, discriminated union types, but I'll save those for another blog entry.

No comments: