If you don’t have coherence then ideally the typechecker should fail the build telling you that it can’t identify a unique instance, and list the instances it found so you can debug.
EDIT: I will add that type classes/modular implicits don’t really make sense in idiomatic OCaml (at least to me). E.g. here’s one of the motivating examples in the paper:
module type Show = sig
type t
val show : t -> string
end
let show {S : Show} x = S.show x
implicit module Show_int = struct
type t = int
let show x = string_of_int x
end
But…we don’t program like this in OCaml now. Instead, we pack all the members needed into the original module that contains the type. Or we create a new expanded module that include
s the original module and expands on it. The point is we pack in all the members needed for a module to conform to all the interfaces we need it to. E.g.,
module Int = struct
type t = int
let show = string_of_int
(* ...other members... *)
end
Now Int
automatically conforms to Show
, and with its other members, to any of a bunch of other interfaces. To me this is one of the basic principles of modular programming in OCaml, and trying to move towards a more Haskell style where we split up and parcel out a single module’s functionality into many small modules to make them ‘instances’…seems like an unnatural style. OCaml modules already support subtyping and conformance. Haskell type class instances don’t work in that way. The design spaces are different and imho that’s OK.