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
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