Units of Measure
Units at Runtime
Units of Measure are used only for static checking by the compiler, and are not available at runtime. They cannot be used in reflection or in methods like
For example, C# gives a
double with no units for a field of type
float<m> defined by and exposed from an F# library.
Conversions between units
Note that the F# compiler does not know that
100<cm>. As far as it cares, the units are separate types. You can write similar functions to convert from meters to kilograms, and the compiler would not care.
It is not possible to define units of measure as multiples of other units such as
However, to define units "per something", for example Hertz, measuring frequency, is simply "per second", is quite simple.
Ensuring Consistent Units in Calculations
Units of measure are additional type annotations that can be added to floats or integers. They can be used to verify at compile time that calculations are using units consistently.
To define annotations:
Once defined, annotations can be used to verify that an expression results in the expected type.
Unit-of-measure type parameters
[<Measure>] attribute can be used on type parameters to declare types that are generic with respect to units of measure:
Use standardized unit types to maintain compatibility
For example, types for SI units have been standardized in the F# core library, in
Microsoft.FSharp.Data.UnitSystems.SI. Open the appropriate sub-namespace,
UnitSymbols, to use them. Or, if only a few SI units are required, they can be imported with type aliases:
Some users tend to do the following, which should not be done whenever a definition is already available:
The difference becomes apparent when interfacing with other code that refers to the standard SI types. Code that refers to the standard units is compatible, while code that defines its own type is incompatible with any code not using its specific definition.
Therefore, always use the standard types for SI units. It doesn't matter whether you refer to
UnitSymbols, since equivalent names within those two refer to the same type:
Using LanguagePrimitives to preserve or set units
When a function doesn't preserve units automatically due to lower-level operations, the
LanguagePrimitives module can be used to set units on the primitives that support them:
To assign units of measure to a double-precision floating-point value, simply multiply by one with correct units:
To assign units of measure to a unit-less value that isn't System.Double, for example, arriving from a library written in another language, use a conversion:
Here are the function types reported by F# interactive: