Units of measure #
A unit of measure over a set B of base units is a ℚ-valued exponent vector:
a function B → ℚ recording the power of each base unit.
Units are written multiplicatively (m * s⁻¹, m ^ (-1/2 : ℚ)), so the
carrier is Multiplicative ℚ pointwise. Unit multiplication is then exponent
addition, and Pi.commGroup supplies the whole abelian group structure.
Why ℚ and not ℤ #
Two independent reasons, recorded because the choice looks like an extravagance and is not:
- It is forced by the domain. A normalized three-dimensional wavefunction
carries
m ^ (-3/2); volatility carriesTime ^ (-1/2). Neither is expressible with integer exponents, which is why no existing static units system can type either one. - It makes the solver simpler, not harder. Over
ℤthe unit group is a lattice and unification needs Hermite or Smith normal form; overℚit is a vector space and unification is Gaussian elimination.
A unit of measure over base units B: a ℚ-valued exponent vector,
written multiplicatively.
Equations
- LambdaS.Uom B = (B → Multiplicative ℚ)
Instances For
Build a unit from an exponent vector.
Equations
- LambdaS.Uom.ofExp f b = Multiplicative.ofAdd (f b)
Instances For
Rational powers are written u ^ q, exactly as on paper.
Equations
- LambdaS.Uom.instHPowRat = { hPow := LambdaS.Uom.rpow }
The exponent group is torsion-free, over ℚ here and over ℤ equally, so a unit equal to its own inverse is trivial.
This single fact is what forces the Cholesky factor into the dimensionless
space in LambdaS.Map. The contrast it needs is a group with torsion, say
ℤ/2ℤ-graded exponents, not the integer exponents of [Kennedy 1997]; for what
the rational exponents do buy, see rpow_nth_root above.