Hello!
Would appreciate very much if someone could help me understand the behavior of this OCaml snippet:
open Core
module IntSet = Set.Make(Int)
module IntMap = Map.Make(Int)
let test = fun (x : IntSet.t) -> (IntMap.of_key_set x)
(* this quite literally expands the definition of Set.Make and Map.Make *)
module MakeSet (Elt : Set.Elt) = Set.Make_using_comparator(struct
include Elt
include Comparator.Make(Elt)
end)
module MakeMap (Key : Map.Key) = Map.Make_using_comparator(struct
include Key
include Comparator.Make(Key)
end)
module IntSet = MakeSet(Int)
module IntMap = MakeMap(Int)
let test = fun (x : IntSet.t) -> (IntMap.of_key_set x)
Basically, this explores the compatibility of the Key type of a Map with int keys and a set with int elements, which comes up eg. when creating a map from a set. The first test is the “naive” way to create the set and map, using the Make functors. It fails, because the phantom comparator_witness types created by Set.Make and Map.Make are deemed to be different. I don’t really get why , because both Make functors create these witness types in the exact same way on the exact same argument, and I have ascribed neither IntSet or IntMap to hide anything about comparator_witness.
The second method quite literally expands the definition of Set.Make and Map.Make from the library source, and now all of a sudden the test works. So what is it about Make that is causing OCaml to “forget” that the comparator_witness types are in fact the same…
Thank you!