Today’s random F# code: Using measures to give types more meaning

We use NodaTime in our application to deal with time. As you may remember, time is very important in our application – it’s a attendance time-tracking tool with duty planning and many more features. For example, we use Instant to model a point in time. But sometimes, we need a point in time with a granularity of minutes, not nanoseconds. Instead of introducing our own type to model an instant with minute granularity, we use an Instant with a measure. Let’s see how this works:

Define the measure and some helper functions

First, we must define that an Instant may have a measure associated with the MeasureAnnotatedAbbreviation attribute on a type alias.

Then we define the measure MinuteGranularity. Finally, we implement the conversion methods to get an Instant<MinuteGranularity> from an Instant and vice versa.

The #nowarn "42" is needed to allow the cast function to build without warnings because this is some IL hacking.

Now we can use the Measure in type definitions:

And we can assign values like this (instant is of type Instant):

Advantages of measures

Instead of using measures, we could introduce a new type for an instant with minute granularity. But we prefer measures because a type with a measure can be directly JSON serialized, like a normal Instant.

FSharp.UMX

If you find this approach interesting, then also have a look at FSharp.UMX, which provides the possibility to add measures to primitive, non-numeric types out of the box (like DefaultActivitiesEventId in the code sample above).

About the author

Urs Enzler

1 comment

By Urs Enzler

Recent Posts