Module 如何定义其模块实现由函子参数化的模块签名

Module 如何定义其模块实现由函子参数化的模块签名,module,functional-programming,ocaml,functor,Module,Functional Programming,Ocaml,Functor,假设我有一个模块M,由模块F参数化: module M (F : sig type id type data end) = struct type idtype = F.id type datatype = F.data type component = { id : idtype; data : datatype } let create id data = { id; data } let get_comp_data comp = comp.data let get_comp_i

假设我有一个模块
M
,由模块
F
参数化:

module M (F : sig type id type data end) =
struct
 type idtype = F.id
 type datatype = F.data
 type component = { id : idtype; data : datatype }
 let create id data = { id; data }
 let get_comp_data comp = comp.data
 let get_comp_id comp = comp.id
end
所以我是这样用的:

module F1 = struct type id = int type data = float end
module MF1 = M(F1)

let comp = MF1.create 2 5.0
let id = MF1.get_comp_id comp
现在,如果我想要
M
匹配签名
S

module type S = 
sig
  type idtype
  type datatype 
  type component
  val create : idtype -> datatype -> component
  val get_comp_data : component -> datatype
  val get_comp_id : component -> idtype
end

module F1 = struct type id = int type data = float end
module MF1 = (M(F1) : S)

let comp = MF1.create 2 5.0
let id = MF1.get_comp_id comp
这里让我困扰的是,为了定义
获取公司数据
获取公司id
,我需要
在模块
S
中指定
idtype
datatype
;现在想象一下,我在
M
中有其他记录类型和它们自己的类型,我将在
S
中指定十几种类型?有没有更简单的方法来避免这种情况

这样做的自然方式是在定义站点而不是使用站点密封模块。那么您只需要表示一次类型共享:

module M (F : sig type id type data end) :
  S with type idtype = F.id and datatype = F.data
  = struct ... end
如果函子参数更复杂,那么您也可以只共享整个模块而不是单个类型。例如:

module type TYPES = sig type id type data (* ...and more... *) end

module type S = 
sig
  module Types : TYPES
  type component
  val create : Types.id -> Types.data -> component
  val get_comp_data : component -> Types.data
  val get_comp_id : component -> Types.id
end

module M (F : TYPES) : S with module Types = F
  = struct ... end
或者,您甚至可以将签名本身参数化,方法是将其嵌套到另一个函子中:

module type TYPES = sig type id type data (* ...and more... *) end

module S (F : TYPES) =
struct
  module type S =
  sig
    type component
    val create : F.id -> F.data -> component
    val get_comp_data : component -> F.data
    val get_comp_id : component -> F.id
  end
end

module M (F : TYPES) : S(F).S
  = struct ... end

不知道您可以将一个模块放置在另一个同名模块中;肮脏的