Units of Measure

F# has the concept of units of measure. In essence we can declare a unit of measure on a numerical type which associates the numeric with a specific “measurement type” of data. For example, we might define a value as one of the imperial unit of measure, such as lb. Such as

As you can see, declare a unit of measure we use the [<Measure>] attribute as follows

[<Measure>]
type lb

We can now use this unit on a type as follows

let weightInPounds = 100<lb>

The inferred type here is val weightInPounds : int = 100, so as you can see the unit of measure is tied to the type (in this case an int).

If we wish to add or subtract to/from the weightInPounds we might be tempted to write

let newWeight = weightInPounds - 2

But we’ll get the following error The type ‘int’ does not match the type ‘int. This is because the 2 is simply an int and we’d need convert to the same unit of measurements, as per

let newWeight = weightInPounds - 2<lb>

However using multiplication or division will work without the need for the unit of measure added, so the following is perfectly fine

let newWeight = weightInPounds * 2

Deriving units of measurement from existing units of measurement

We can also derived new units of measurement from existing ones. So assuming we have the following

[<Measure>]
type lb

[<Measure>]
type inch

We might create a psi (pounds per square inch) as follows

[<Measure>]
type psi = lb inch^2

We could also apply multiple units of measurement as part of the let binding, for example

let p = 12<lb inch^2>

Removing a unit of measure

In some cases we might want to remove the unit of measure from a value, for example maybe we have a method that takes an int. We will get a compile time error stating “The expression was expected to have type in but here has type int“. We can simply cast

The code below is trying to set the value i (which we’ve setup to be an int) with a unit of measure value (where weight is shown as an int).

let weight = 12<kg>

let i : int = int weight

Writing to the console

To output a value with a unit of measure, using printn, we don’t use the following

let weight = 12<kg>

printfn "%A" weight