Previous: Field access functions, Up: Types   [Contents]


3.5 The standard ordering

For (almost) every Mercury type there exists a standard ordering; any two values of the same type can be compared under this ordering by using the builtin.compare/3 predicate. The ordering is total, meaning that the corresponding binary relations are reflexive, transitive and anti-symmetric. The one exception is higher-order types, which cannot be unified or compared; any attempt to do so will raise an exception.

The existence of this ordering makes it possible to implement generic data structures such as sets and maps, without needing to know the specifics of the ordering. Furthermore, different platforms often have their own natural orderings which are not necessarily consistent with each other. As such, the standard ordering for most types is not fully defined.

For the primitive integer types, the standard ordering is the usual numerical ordering. Implementations should reject code containing overflowing integer literals.

For the primitive type float, the standard ordering approximates the usual numerical ordering. If the result of builtin.compare/3 is (<) or (>) then this relation holds in the numerical ordering, but this is not necessarily the case for (=) due to lack of precision. In the standard ordering, “negative” and “positive” zero values are equal. Implementations should replace overflowing literals with the infinity of the same sign; in the standard ordering positive infinity is greater than all finite values and negative infinity is less than all finite values. Implementations must throw an exception when comparing a “not a number” (NaN) value.

For the primitive type char, the standard ordering is the numerical ordering of the Unicode code point values.

For the primitive type string, the standard ordering is implementation dependent. The current implementation performs string comparison using the C strcmp() function, the Java String.compareTo() method, and the C# System.String.CompareOrdinal() method, when compiling to C, Java and C# respectively.

For tuple types, corresponding arguments are compared, with the first argument being the most significant, then the second, and so on.

For discriminated union types (other than subtypes), if both values have the same principal constructor then corresponding arguments are compared in order, with the first argument being the most significant, then the second, and so on. If the values have different principal constructors, then the value whose principal constructor is listed first in the definition of the type will compare as less than the other value. There is one exception from this rule: in types that are subject to a foreign_enum pragma, the outcomes of comparisons are decided by user’s chosen foreign language representations, using the rules of the foreign language.

For subtypes, the two values compare as though converted to the base type. The ordering of constructors in a subtype definition does not affect the standard ordering.


Previous: Field access functions, Up: Types   [Contents]