Units of Measure

Units exist only at compile time (erased at runtime: zero cost). They're great for physics, finance (currencies), and preventing unit-mixing bugs.

[<Measure>] type m          // meters
[<Measure>] type s          // seconds
[<Measure>] type kg
[<Measure>] type N = kg m / s^2   // derived unit

let distance = 100.0<m>
let time = 9.58<s>
let speed = distance / time        // float<m/s>: 10.438...
let mass = 70.0<kg>
let acceleration = 9.81<m/s^2>
let force: float<N> = mass * acceleration   // checked at compile time
// let wrong = distance + time    // compile error: units don't match

let toKm (d: float<m>) = d / 1000.0<m>      // dimensionless result
[<Measure>] type km
let metersPerKm = 1000.0<m/km>
let convert (d: float<km>) = d * metersPerKm   // float<m>

// Generic over units
let average (xs: float<'u> list) = List.sum xs / float xs.Length
average [ 1.0<m>; 3.0<m> ]                     // 2.0<m>

// Stripping units for interop
let raw = float speed                           // float (unitless)
let withUnit = LanguagePrimitives.FloatWithMeasure<m> 5.0