This is an open question but I never managed to find a solution that pleases me.
Let's say I have this algebraic data type :
type t = A of int | B of float | C of string
Now, let's say I want to write a compare
function - because I want to put my values in a Map
, for example - I'd write it like this :
let compare t1 t2 =
match t1, t2 with
| A x, A y -> compare x y
| A _, _ -> -1
| _, A _ -> 1
| B x, B y -> compare x y
| B _, _ -> -1
| _, B _ -> 1
| C x, C y (* or _ *) -> compare x y
Or I could write it like this :
let compare t1 t2 =
match t1, t2 with
| A x, A y -> compare x y
| B y, B x -> compare x y
| C x, C y -> compare x y
| A _, _
| B _, C _ -> -1
| _ -> 1
If I'm not wrong, saying that n
is the number of constructors, the first compare
will have 3 * (n - 1) + 1
cases and the second one will have n + ((n - 2) * (n - 1)) / 2 + 2
cases.
This is pretty unsatisfying since :
n = 3
(our case) : 7 or 6 casesn = 4
: 10 or 8 casesn = 5
: 13 or 13 cases
It grows pretty fast.
So, I was wondering, do you do it like I do or do you use another method ?
Or, even better, is there the possibility of doing something like
let compare t1 t2 =
match t1, t2 with
| c1 x, c2 y ->
let c = compare c1 c2 in
if c = 0 then compare x y else c
Or,
let compare (c1 x) (c2 y) =
let c = compare c1 c2 in
if c = 0 then compare x y else c
Edit : added a compare if the two constructors are equal for señor Drup (from Guadalup ;-P)
A 1
andA 2
are equals. – Drup