At the start of looking at units, we looked at Unit<U : Unit<U>> and ReifiedUnit<U: Unit<U>, RU: ReifiedUnit<U, RU>>.

Lets take a second look at why these are needed, and why they work.

Firstly, these generics allow for generic family lock-in, basically, code can be written that is generic across all of RU: ReifiedUnit<U, RU>, and once you use a specific unit there, nothing else can be used, by using RU rather than just ReifiedUnit<U: Unit>, we ensure that only Distances can be used, as opposed to any ReifiedUnit<DistanceUnit>, which means we can rely on the properties and functions of Distance. The same applies for Unit<U: Unit<U>>. We use this cycle to define a family, like DistanceUnit which extends Unit<DistanceUnit>, this means that DistanceUnit needs to be able to handle conversion between itself and any other DistanceUnit but not any Unit.

This is a fairly complex usage of generics and type systems, so don’t worry if you don’t get it.

The basic idea, is that we can write code that works for any ‘RU’ or ‘U’ and guarantee that it locks to that one, once its used.