Less Defects with F# Units of Measure

One of the most powerful things that F# has is its ability to create custom units of measure. F# allows you to set an explicit type to a unit. That’s right…you will get compile time checking on any of the units that you use within your application.

If your application does use any type of units, then determining what type of unit the input or output is expecting can be tricky. Even NASA has had this problem before. With the compile time checking of any discrepancies for the units, then these types of bugs will disappear all together.

For the most used units Microsoft already has them built in and can be directly used.

open Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols

let meter = 1<m>

But for custom units they can be easily defined using the Measure attribute.

[<Measure>] type pixel
[<Measure>] type inch

Then we can use them like normal values except, as you can see, the pixels value is strongly typed as an int of pixel.

let pixels = 200<pixel>

val pixels : int<pixel> = 200

Both units can be used in creating values for calculations…

let pixelsPerInch = 300<pixel/inch>

Or even as a totally new unit.

[<Measure>] type ppi = pixel/inch

Within our calculation, if we specify what unit to multiply with we’ll get a correct result type. In this example we end up with 600 pixels.

let ppi = pixelsPerInch * 2<inch>

val ppi : int<pixel> = 600

Omit the inch type in the calculation and you get a different type – pixel/inch.

let ppi = pixelsPerInch * 2

val ppi : int<pixel/inch> = 600

Now let’s say we have a function to do some other calculation.

let pixelsByGivenInches inches: float<pixel/inch> =
    inches + 1.0

But this will result in a compilation error.

unitOfMeasureError

Instead we need to specify what unit we want to do the calculation in.

let pixelsByGivenInches inches: float<pixel/inch> =
    inches + 1.0<pixel/inch>

If we run this in the interactive our result will actually be the type float of pixel/inch.

val pixelsByGivenInches : inches:float<pixel/inch> -> float<pixel/inch>

And now we can use the above function and pass in the correct type in its parameter.

pixelsByGivenInches 2.0<pixel/inch>

val it : float<pixel/inch> = 3.0

Hopefully this helped to understand another really useful feature that F# has to offer, especially in the world of real world applications that can be used for the enterprise as well as for science.

Of course, much more information can be found at F# For Fun and Profit and MSDN.

Stay Informed

Sign up for the latest blogs, events, and insights.

We deliver solutions that accelerate the value of Azure.
Ready to experience the full power of Microsoft Azure?

Atmosera is thrilled to announce that we have been named GitHub AI Partner of the Year.

X