Reputation: 777
I am trying to create a module that exposes a set without exposing the type of the elements in the set. Here is a simplified version:
open Core
module type M_t = sig
module Id : Comparator.S
val set : (Id.t, Id.comparator_witness) Set_intf.Tree.t
end
module M : M_t = struct
module Id = Int
module S = Set.Make (Id)
let set = S.empty
end
With this signature, client applications could use the M_t
signature and not know that under the hood, set
contains int
s. Not only is my implementation not particularly idiomatic, but it doesn't compile:
❯ dune build
File "hello_world.ml", lines 9-14, characters 17-3:
9 | .................struct
10 | module Id = Int
11 | module S = Set.Make (Id)
12 |
13 | let set = S.empty
14 | end
Error: Signature mismatch:
...
Values do not match:
val set : S.t
is not included in
val set : (int, Id.comparator_witness) Set_intf.Tree.t
File "hello_world.ml", line 6, characters 2-57: Expected declaration
File "hello_world.ml", line 13, characters 6-9: Actual declaration
I have found everal similar questions but I haven't succeeded in transferring the answers to my setting, so I apologize if this is a duplicate.
Upvotes: 1
Views: 44
Reputation: 4441
The solution I could come up with is the following:
open Core
module type M_t = sig
module Id : Comparator.S
module S : Set.S with type Elt.t = Id.t
val set : S.t
end
module M : M_t = struct
module Id = Int
module S = Set.Make (Id)
let set = S.empty
end
The thing is I couldn't find a way to force Elt.comparator_witness
to be equal to Id.comparator_witness
and this is the closest working solution I got to correspond to your initial problem (I'm not a Core user).
Upvotes: 1