FSharp.Azure logo

This week I published the 1.0 stable release of FSharp.Azure on NuGet. Compared to the beta, it has one extra feature I slipped in: support for using option types on your record fields.

For those unfamiliar with F#, the option type is an F# construct that allows you to express the presence or absence of a value. It is similar to Nullable<T>, however it works for all types, instead of just value types. C# developers are used to using null as the “absence” value for reference types, as all references are nullable by default in the CLR. However, when writing F# any type you define is not allowed to be nullable by default, regardless of the fact that it may be a CLR reference type under the covers. This is where the F# option type comes in; when you want to allow the absence of something, you must be explicit and describe that fact using the option type. This is great because it means that you are much less likely to be passed null (ie. the “absence”) when you don’t expect it and get an error such as the irritating NullReferenceException. You can basically view the option type as opt-in nullability.

Here’s an example record type for use with FSharp.Azure that uses option types:

type Game = 
    { [<PartitionKey>] Developer : string
      [<RowKey>] Name : string
      ReleaseYear : int option
      Notes : string option }

You could insert one of these records into table storage like this:

let game = 
    { Developer = "343 Industries"
      Name = "Halo 5"
      ReleaseYear = None
      Notes = None }

let result = game |> Insert |> inGameTable

The inGameTable function is a FSharp.Azure helper function and you can see how it was defined in this previous post.

Note the use of the None value for ReleaseYear and Notes. We’re explicitly saying we’re omitting a value for those two fields. When translated to Azure table storage this means for the row that will be inserted for this record those two properties will not be defined. Remember that in table storage, unlike relational databases, not all rows in a table need have the same properties.

If we later want to update that record in table storage and provide values for ReleaseYear and Notes, we can:

let modifiedGame =
    { game with
      ReleaseYear = Some 2015
      Notes = Some "Has yet to be released." }

let result = modifiedGame |> ForceReplace |> inGameTable

Another nice ability that using option types with FSharp.Azure provides us is being able to use Merge to update the row in table storage with only the properties that are either not option types or are option typed and have Some value (ie are not None). For example:

let modifiedGame =
    { game with
      ReleaseYear = None
      Notes = Some "Will be bigger than Halo 4!" }

let result = modifiedGame |> ForceMerge |> inGameTable

Because we’re using a Merge operation, the above will change the Notes property in table storage, but will not change the existing ReleaseYear value.

To play with FSharp.Azure, use NuGet to install the package “FSharp.Azure”. The source code is available on GitHub.