Ocaml 使用抽象模块作为与模块分离的类型定义的一部分

Ocaml 使用抽象模块作为与模块分离的类型定义的一部分,ocaml,Ocaml,我试图使用模块类型Partial\u information,它是通过functorMake\u Partial\u information构造的,作为typeCell.t中字段内容的类型。但是,我得到了错误未绑定模块部分\u信息 open Core (* module which is used as argument to functor *) module type Partial_type = sig type t val merge : old:t -> new_:t

我试图使用模块类型
Partial\u information
,它是通过functor
Make\u Partial\u information
构造的,作为type
Cell.t
中字段
内容的类型。但是,我得到了错误
未绑定模块部分\u信息

open Core

(* module which is used as argument to functor *)
module type Partial_type = sig
  type t
  val merge : old:t -> new_:t -> t
end

(* type of result from functor *)
module type Partial_information = sig
  type a
  type t = a option
  val merge : old:t -> new_:t -> t
  val is_nothing : t -> bool
end

(* The functor *)
module Make_partial_information(Wrapping : Partial_type):
  (Partial_information with type a = Wrapping.t)
= struct
  type a = Wrapping.t
  type t = a option

  let merge ~(old : t) ~(new_ : t) =
    match (old, new_) with
    | (None, None) -> None
    | (None, Some a) -> Some a
    | (Some a, None) -> Some a
    | (Some a, Some b) -> (Wrapping.merge ~old:a ~new_:b) |> Some

  let is_nothing (it: t) : bool = (is_none it)
end

(* Checking to make sure understanding of functor is correct *)
module Int_partial_type = struct
  type t = int
  let merge ~old ~new_ = new_ [@@warning "-27"]
end

module Int_partial_information = Make_partial_information(Int_partial_type)

(* Trying to use _any_ type which might have been created by the functor as a field in the record *)
module Cell = struct
  type id = { name : string ; modifier : int }
  type t = {
    (* Error is here stating `Unbound module Partial_information` *)
    contents : Partial_information.t ;
    id : id
  }
end


模块类型是模块的规范。它们不自己定义类型。它们也不是由函子以任何方式构造的。 因此,很难说出你想做什么。 据我所知,您可以简单地使用函子定义单元格类型:

module Cell(P : Partial_information) = struct
  type id = { name : string ; modifier : int }
  type partial
  type t = {
    contents : P.t;
    id : id
  }
end
或者,使细胞类型具有多态性可能更简单:

  type 'a cell = {
    contents : 'a;
    id : id
  }
因为类型本身不是特别有趣,也不是真正依赖于 内容的类型

附言: 可以使用第一类模块和GADT对模块类型的特定实现进行存在性量化。但目前尚不清楚是否值得在这里大幅增加您的复杂性预算:

type 'a partial_information = (module Partial_information with type a = 'a)
module Cell = struct
  type id = { name : string ; modifier : int }
  type t = E: {
    contents : 'a ;
    partial_information_implementation: 'a partial_information;
    id : id
  } -> t
end

为了阐明GADT示例,类型参数
'a
内容
部分信息实现
字段之间共享,这两个字段约束这两个字段,以确保给定类型的模块实现?是。GADT向您提供的信息是,存在某种未知类型的
'a
,因此
内容
属于
'a
类型,而
部分信息的实现
是该类型
'a
的部分信息的实现。结果是,您只能将
内容
值与打包在
部分模块信息
中的函数一起使用。