首页 > 解决方案 > 使用抽象模块作为与模块分开的类型定义的一部分

问题描述

我正在尝试使用Partial_information通过仿函数构造的模块类型Make_partial_information作为 type 中字段contents的类型Cell.t。但是,我得到了错误Unbound module Partial_information

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

标签: ocaml

解决方案


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

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
  }

因为类型本身并不是特别有趣,也不是真正依赖于内容的类型。

PS:可以使用第一类模块和 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

推荐阅读