Is there a way to instantiate the Map.Make functor with polymorphic variant ?
Without writing by hand a module like
module Keys = struct
type t= `Foo | `Bar
let compare a b = match a, b with
| `Foo, `Bar -> 1
| `Foo, `Foo -> 0
| `Bar, `Bar -> 0
| `Bar, `Foo -> -1
end
module KeysMap = Map.Make(Keys)
the compare function is heavy, is there to way to make better ?
Most of those harmful points don’t really apply here for such a simple type though.
Sure, using Stdlib.compare blindly is a problem, but in this case structural comparison is exactly the goal (and it’s very simple structure).
The good way to use it here is to monomorphize it:
let compare (a: t) (b: t) = Stdlib.compare a b
Now the compiler can produce very efficient code that doesn’t require calling the generic caml_compare function from the runtime. This can be quickly seen with Godbolt: Compiler Explorer (compare3 is longer than the red highlighting seems to suggest).
Strongly agree here! There is a big difference between the polymorphic comparison C primitive (caml_compare, implemented in runtime/compare.c) and the lambda primitive %compare (Stdlib.compare is this latter one). It’s a shame to end up writing masses of code (and often generating more complex code) rather than a simple type annotation.