如何满足包含多态集的模块类型

问题描述

我正在尝试创建一个公开集合而不公开集合中元素类型的模块。这是一个简化版本:

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

使用此签名,客户端应用程序可以使用 M_t 签名,并且不知道在幕后,set 包含 int。我的实现不仅不是特别惯用,而且不能编译:

❯ 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

我发现了所有类似的问题,但我没有成功地将答案转移到我的设置中,所以如果这是重复的,我深表歉意。

解决方法

我能想到的解决方案如下:

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

问题是我找不到强制 Elt.comparator_witness 等于 Id.comparator_witness 的方法,这是我得到的与您最初的问题最接近的工作解决方案(我不是核心用户)。