OCaml Stdlib compare documentation states ...
val compare : 'a -> 'a -> int
compare x y returns 0 if x is equal to y, a negative integer if x is less than y, and a positive integer if x is greater than y. The ordering implemented by compare is compatible with the comparison predicates =, < and > defined above, with one difference on the treatment of the float value nan. Namely, the comparison predicates treat nan as different from any other float value, including itself; while compare treats nan as equal to itself and less than any other float value. This treatment of nan ensures that compare defines a total ordering relation.
compare applied to functional values may raise Invalid_argument. compare applied to cyclic structures may not terminate.
The compare function can be used as the comparison function required by the Set.Make and Map.Make functors, as well as the List.sort and Array.sort functions.
Now we have two notion(s) of equality in OCaml, namely...
Structural Equality: Expressed using operator =, the type of which is
# (=);;
- : 'a -> 'a -> bool = <fun>
Physical Equality: Expressed using operator ==, the type of which is
# (==);;
- : 'a -> 'a -> bool = <fun>
As we can see, the type of both is same, but the function application of both of them is different when it comes to function value as arguments.
Structural Equality doesn't hold over function values, but Physical Equality may. Trying to compare(as in =) with function values throws. And as stated in the documentation of Stdlib.compare, it uses structural equality.
Illustration: Structural Equality with Function Values
# let f x = x;;
val f : 'a -> 'a = <fun>
# let g x = x;;
val g : 'a -> 'a = <fun>
# f = g;;
Exception: Invalid_argument "compare: functional value".
# g = f;;
Exception: Invalid_argument "compare: functional value".
Illustration: Physical Equality with Function Values
# let f x = x;;
val f : 'a -> 'a = <fun>
# let g x = x;;
val g : 'a -> 'a = <fun>
# f == g;;
- : bool = false
# f == f;;
- : bool = true
# g == g;;
- : bool = true
# g == f;;
- : bool = false
# let h x y = x + y;;
val h : int -> int -> int = <fun>
# h == f;;
Error: This expression has type int -> int
but an expression was expected of type int -> int -> int
Type int is not compatible with type int -> int
So in short, I don't think we can use Stdlib.compare with Set.Make with function values.
So ...
- Either, we will have to keep the
type t in Action module to something over which structural equality can be applied if we have to continue using Stdlib.compare.
- Or, implement
compare of your own so that it can do something with those function values as arguments, along with satisfying the function contract of val compare : t -> t -> int as mandated by Set.OrderedType module type.
WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET