I can't seem to find reference on why does this not work:
- (2000,1)<(2000,1);
stdIn:18.1-18.18 Error: operator and operand don't agree [overload]
operator domain: 'Z * 'Z
operand: (int * int) * (int * int)
in expression:
(2000,1) < (2000,1)
Does Standard ML support structural comparison?
The short answer: Only for equality.
The strictly less than operator (<) in the top level environment is as the other comparison operators a bit "special". They are "special" in the way that they are (as the only ones) overloaded to work with both integers, reals, etc. Also the somewhat special thing about this overloading is that integer is used if a type can't be inferred (e.g., a polymorphic type was inferred 'a
).
For the case of integers the Int.<
function is used, which only takes two integers as argument
- Int.<;
val it = fn : int * int -> bool
However for equality, the case is a bit different, as seen by the type of the equality operator
- op=;
val it = fn : ''a * ''a -> bool
Here the polymorphic type is seen to bee ''a
, note the double plings. This is because it can only be instantiated to an equality type (e.g., int, string, int'string, etc.). Note that real is not an equality type!
Update
The thing I normally do is to make a compare function for each (data)type i create. This way I have full control over what happens. The idea of the compare function is to return an order
datatype order = LESS | EQUAL | GREATER
With this you can easily make a case expression and do the appropriate thing, instead of a if .. < .. then .. else ..
Update1
Below code is from Andreas Rossberg's comment. I have included it here for easy reading
fun comparePair compareA compareB ((a1, b1), (a2, b2)) =
case compareA (a1, a2) of
EQUAL => compareB (b1, b2)
| other => other
And some examples of use
- comparePair Int.compare String.compare ((2, "foo"), (3, "bar"));
val it = LESS : order
- comparePair Int.compare String.compare ((3, "bar"), (3, "bar"));
val it = EQUAL : order