The
Ord class is used for totally ordered datatypes.
Instances of
Ord can be derived for any user-defined datatype
whose constituent types are in
Ord. The declared order of the
constructors in the data declaration determines the ordering in
derived
Ord instances. The
Ordering datatype allows a
single comparison to determine the precise ordering of two objects.
Ord, as defined by the Haskell report, implements a total order
and has the following properties:
- Comparability x <= y || y <= x =
True
- Transitivity if x <= y && y <=
z = True, then x <= z = True
- Reflexivity x <= x = True
- Antisymmetry if x <= y && y <=
x = True, then x == y = True
The following operator interactions are expected to hold:
- x >= y = y <= x
- x < y = x <= y && x /= y
- x > y = y < x
- x < y = compare x y == LT
- x > y = compare x y == GT
- x == y = compare x y == EQ
- min x y == if x <= y then x else y = True
- max x y == if x >= y then x else y = True
Note that (7.) and (8.) do
not require
min and
max to return either of their arguments. The result is merely
required to
equal one of the arguments in terms of
(==).
Users who expect a stronger guarantee are advised to write their own
min and/or max functions.
The nuance of the above distinction is not always fully internalized
by developers, and in the past (tracing back to the Haskell 1.4
Report) the specification for
Ord asserted the stronger
property that
(min x y, max x y) = (x, y) or
(y, x),
or in other words, that
min and
max will return
one of their arguments, using argument order as the tie-breaker if the
arguments are equal by comparison. A few list and
Foldable
functions have behavior that is best understood with this assumption
in mind: all variations of
minimumBy and
maximumBy
(which can't use
min and
max in their implementations)
are written such that
minimumBy compare and
maximumBy compare are respectively equivalent to
minimum and
maximum (which do use
min and
max) only if
min and
max adhere to this
tie-breaking convention. Otherwise, if there are multiple least or
largest elements in a container,
minimum and
maximum
may not return the
same one that
minimumBy
compare and
maximumBy compare do (though
they should return something that is
equal). (This is relevant
for types with non-extensional equality, like
Arg, but also in
cases where the precise reference held matters for memory-management
reasons.) Unless there is a reason to deviate, it is less confusing
for implementors of
Ord to respect this same convention (as the
default definitions of
min and
max do).
Minimal complete definition: either
compare or
<=.
Using
compare can be more efficient for complex types.