Reading — step 1 of 4
Learn
Units of measure add type-level units to numbers. Compile-time-checked, zero-cost.
[<Measure>] type m // meters
[<Measure>] type s // seconds
[<Measure>] type kg // kilograms
let distance: float<m> = 100.0<m>
let time: float<s> = 9.58<s>
let speed = distance / time // float<m/s>
The inferred unit is m/s — meters per second. The compiler tracks units through arithmetic.
Mixing fails at compile time:
let bad = distance + time // ERROR — can't add m and s
Derived units:
[<Measure>] type N = kg * m / s^2 // newton
[<Measure>] type J = N * m // joule
Common conversion functions — manual:
let feetToMeters (ft: float<ft>) : float<m> =
ft * 0.3048<m/ft>
The constant has unit m/ft — multiplying gives the right unit for the result.
Currency:
[<Measure>] type USD
[<Measure>] type EUR
let wallet: decimal<USD> = 100m<USD>
let exchange = 0.92m<EUR/USD>
let inEur = wallet * exchange // decimal<EUR>
No more accidentally adding USD to EUR. The Mars Climate Orbiter (lost in 1999 due to a unit mismatch between metric and imperial) wouldn't have happened in F#.
LanguagePrimitives.X<unit> for runtime-known units:
LanguagePrimitives.FloatWithMeasure<m> 3.14 // 3.14<m>
Caveats:
- Only on numeric types (int, float, decimal, etc.)
- Erased at runtime —
float<m>is just afloat - Doesn't catch ALL unit bugs (negative, ratio-based)
For financial code, scientific code, anywhere unit confusion matters — units of measure are a free correctness boost.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…