Assume such measures are defined:
[<Measure>] type kilogram
[<Measure>] type kg = kilogram
[<Measure>] type s
When I define a binding like this:
let x = 1.<kg / kilogram> // Type of x: float
F# correctly simplifies type of x from float<kg/kilogram>
to float
.
But when I add another unit like this:
let y = 1.<kg s / kilogram> // Type of y: float<kg s / kilogram>
Instead of simplfying type of y to float<s>
, it shows float<kg s / kilogram>
Why doesn't F# simplify it in this case? Am I doing something wrong?
As far as I can see based on a couple of experiments, the only place where the compiler uses the fact that kg = kilogram
in the simplification process is when the final type is unit-less, i.e. float<1>
type. In all other cases I tried, it keeps both kg
and kilogram
in the unit type.
I suspect the compiler still knows that the type of 1.<kg/kilogram>
is kg/kilogram
, but because this is equivalent to 1
, it does not display it - it shows float
rather than float<1>
or float<kg/kilogram>
.
It is worht noting that the simplificiation happens when it is actually needed - if you try comparing a value 1.<kg s / kilogram>
with a value 1.<s / 1>
, this is well-typed:
let y = 1.<kg s / kilogram>
y = 1.<s/1>
I do not have a solid evidence (like a link to the specification), but I think the compiler only does the simplification when it actually has to, but otherwise keeps the unit annotations as you write them.