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

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,
the C# `System.String.CompareOrdinal()`

method, and
the Erlang term comparison operators,
when compiling to C, Java, C# and Erlang 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,
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.

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