The quote from the specification says that the generated comparison will first compare the tags (that is essentially the index of the constructors), but I'm not sure if this gives you any useful information - because if the union carries some value, you will not know whether the number is distance between the constructors, or the result of the comparison of the contained values. For example:
type Tricky() =
interface System.IComparable with
override x.CompareTo(b) = -2
type DU =
| A of Tricky
| B
| C
// Returns -2 because of the distance between constructors
compare (A (Tricky())) C
// Returns -2 because of the comparison on `Tricky` objects
compare (A (Tricky())) (A(Tricky()))
If you wanted to rely on the ability to get the distance between constructors, it might be safer to use enumerations:
type DU =
| A = 1
| B = 2
| C = 3
Then you can get the distance by converting the values to integers using (int DU.A) - (int DU.C)
.