When I have to do this by hand, my favorite style is this:

type t = A of float | B of string

let compare x y =
   let tag_idx = function  A _ -> 0 | B _ -> 1 in
   match x, y with
   | A a1, A a2 -> Float.compare a1 a2
   | B b1, B b2 -> String.compare b1 b2
   | (B _ | A _), _ -> Int.compare (tag_idx x) (tag_idx y)

You will get the right kind of warnings when the type t changes, and it's pleasantly explicit about the ordering implied by the tags.

That said, this is unpleasant boilerplate to have to write by hand.  My expectation is that in the next release of Core, we will include a set of macros for autogenerating equality, comparison and hash functions, as well as type-hashes, all driven by the type definitions.

On Sat, Apr 30, 2011 at 4:19 PM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
You want to avoid code size quadratic in the number of constructors. Which is possible:
 
let cmp x y = match x, y with
A, A -> true
| A, _ | _, A -> false
| B, B -> true
| B, _ | _, B -> false

With one twist though: if done that way for (type foo = A | B), the last (_, B) pattern is actually redundant. If you want to avoid getting a warning here, you should comment it out or remove it:

  let cmp x y = match x, y with
  | A, A -> true
  | A, _ | _, A -> false
  | B, B -> true
  | B, _ (*| _, B*) -> false

That's the style I use.

On Sat, Apr 30, 2011 at 3:43 PM, craff73@gmail.com <craff73@gmail.com> wrote:
Hello,

You want to avoid code size quadratic in the number of constructors. Which is possible:

let cmp x y = match x, y with
A, A -> true
| A, _ | _, A -> false
| B, B -> true
| B, _ | _, B -> false
...

Cheers
Christophe

--
Envoyé de mon téléphone Android avec K-9 Mail. Excusez la brièveté.