Canonicalization is tough, and requires you to define some common ordering on your units.
Systems will use an array of unit powers, so that if the array were defined as <Joules, Seconds, Newtons, Meters>, then acceleration would be <0,-2,0,1> and watts would be <1,-1,0,0>. Addition and subtraction require that your arrays are equal, and multiplication and division are pairwise additive/subtractive.
Sorry! I never really spent much time in the physical sciences, so I didn't know that. You would obviously not want to pick Joules as a fundamental unit.
Will the Rust compiler ever understand numbers in types? I.e. will the numbers ever be more than just part of the string that is the type name? If not, then I don't know how possible powers will be. Maybe the solution would be to define some types for commonly-used powers, e.g. PowN4, PowN3, PowN2, PowN1, Pow2, Pow3, Pow4. Users who needed higher powers could define those types themselves, I guess.
Great question. I believe each unit struct would need to implement PartialEq or something similar. That would define the canonical nesting order. Alphabetical would make sense.
We would to resolve the nesting during multiplication and division. For example:
let a: Scalar<Times<A, B>> = Scalar::new(10.0);
let b: Scalar<Times<A, Times<B, C>>> = Scalar::new(5.0);
let c: Scalar<Times<A, Times<A, Times<B, Times<C>>>> = a * b;
Another challenge is that the type of c is ugly. But this could be mitigated by generous use of type synonyms.
Systems will use an array of unit powers, so that if the array were defined as <Joules, Seconds, Newtons, Meters>, then acceleration would be <0,-2,0,1> and watts would be <1,-1,0,0>. Addition and subtraction require that your arrays are equal, and multiplication and division are pairwise additive/subtractive.