May 24, 2014 9:47 AM by Daniel Chambers (last modified on May 24, 2014 9:58 AM)
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.