OCaml中模块的构造函数的范围

Sof*_*mur 6 constructor ocaml module

我已经定义了以下接口和模块:

module type TYPE =
  sig
    type t
  end

module Type = (struct
  type t =
    | TBot
    | T of int
    | TTop
end: TYPE)
Run Code Online (Sandbox Code Playgroud)

现在我意识到如果我在外面写Type.T 5,编译器会给我错误Error: Unbound constructor Type.T.如果我删除签名并保留模块,则错误将消失.

1)所以我的第一个问题是,如何更改签名以便我可以在外部使用构造函数?

2)一种方法是如下明确定义构造函数,你认为它是一种传统方式吗?我现在可以看到的一个缺点是它不允许构造TBotTTop.

module type TYPE =
  sig
    type t
    val make : int -> t
  end

module Type = (struct
  ...
  let make (i: int) : t =
      T i
end: TYPE)
Run Code Online (Sandbox Code Playgroud)

3)是否总是需要让外部能够在模块内部构造一个值?

Tho*_*mas 6

1)你必须导出类型声明,否则,t被认为是抽象的,然后你需要定义和导出构造函数(见2)):

module type TYPE = sig
  type t =
    | TBot
    | T of int
    | TTop
end

module Type : TYPE = struct
  type t =
    | TBot
    | T of int
    | TTop
end
Run Code Online (Sandbox Code Playgroud)

2)是的,这是一个非常好的方式.要定义顶部和底部,您只需定义(和导出)新构造函数:

module type TYPE = sig
  ...
  val top: t
  val bot: t
end

module Type = struct
  ...
  let bot = TBot
  let top = TTop
end
Run Code Online (Sandbox Code Playgroud)

3)我不明白你的问题