Types 如何生成OCaml中使用模块定义的类型值?

Types 如何生成OCaml中使用模块定义的类型值?,types,module,ocaml,Types,Module,Ocaml,TL;DR-在OCaml中,如何调用类型类似于类型为'elt set=module BatSet.S且类型为'elt='elt的类型,以及如何生成此类型的值 目前,我正在阅读Tezos协议[*]中的代码,我看到了以下代码 模块类型装箱_集=sig 英语四级考试 英语水平:英语水平相当 模块操作:设置elt=elt类型 瓦尔·博克塞德:行动t val大小:int 终止 类型为“elt set=模块装箱的集合,类型为elt=”elt 我从来没有听说过像type a=module B这样的语法。因此,

TL;DR-在OCaml中,如何调用类型类似于类型为'elt set=module BatSet.S且类型为'elt='elt的类型,以及如何生成此类型的值

目前,我正在阅读Tezos协议[*]中的代码,我看到了以下代码

模块类型装箱_集=sig 英语四级考试 英语水平:英语水平相当 模块操作:设置elt=elt类型 瓦尔·博克塞德:行动t val大小:int 终止 类型为“elt set=模块装箱的集合,类型为elt=”elt 我从来没有听说过像type a=module B这样的语法。因此,我打开了一个顶级OCaml解释器,并使用该模块重现了类似的用法。下面的代码是我复制的日志

$ ocaml
        OCaml version 4.07.1

# #use "topfind";;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
  #require "package";;      to load a package
  #list;;                   to list the available packages
  #camlp4o;;                to load camlp4 (standard syntax)
  #camlp4r;;                to load camlp4 (revised syntax)
  #predicates "p,q,...";;   to set these predicates
  Topfind.reset();;         to force that packages will be reloaded
  #thread;;                 to enable threads

- : unit = ()

# #require "batteries";;
[...]: loaded

# type 'elt set = (module BatSet.S with type elt = 'elt);;
type 'elt set = (module BatSet.S with type elt = 'elt)
这个奇怪的类型定义真的很有效,但我坚持在这里。模块本身如何成为一种类型?如何使类型为'elt set'的值像let v:int set=。。。?有什么关键字可以调用这样的类型吗

[*],提交哈希:86B527F7EFD8AA78FCC427776920480C6C0E780

这是具有约束的第一类模块的类型:

此类型可用于将模块打包到值中:

let int_set = ((module BatSet.Make(Int)): int set);;
然后可以将这些值解压缩到模块中,例如,我可以使用它定义一个唯一的\u排序函数:

let unique_sorted (type a) ((module MySet): a set) list =
  let set = List.fold_left (fun set x -> MySet.add x set) MySet.empty list in
  MySet.elements set
let test = assert( unique_sorted int_set [4;0;1;2;2] = [0;1;2;4] )
类似于模块M的类型是一级模块的类型

只需定义具有正确类型的模块,就可以生成此类类型的值

下面是我用来测试这一点的一个简单示例:

# module type B = sig type elt end;;
module type B = sig type elt end
# type 'elt b = (module B with type elt = 'elt);;
type 'elt b = (module B with type elt = 'elt)
# module X = struct type elt = int end;;
module X : sig type elt = int end
# (module X : B with type elt = int);;
- : (module B with type elt = int) = <module>
# ((module X : B with type elt = int) : int b);;
- : (module B with type elt = int) = <module>