Module OCaml中的递归集

Module OCaml中的递归集,module,ocaml,recursion,Module,Ocaml,Recursion,如何在OCaml中定义一个集合,该集合也可以包含其类型的元素 为了解释这个问题,我为很多数据类型做了一个类型声明,比如 type value = Nil | Int of int | Float of float | Complex of Complex.t | String of string | Regexp of regexp | Char of char | Bool of bool | Range of (int*int) list | Tuple of value array |

如何在OCaml中定义一个
集合
,该集合也可以包含其类型的元素

为了解释这个问题,我为很多数据类型做了一个类型声明,比如

type value =
  Nil
| Int of int
| Float of float
| Complex of Complex.t
| String of string
| Regexp of regexp
| Char of char
| Bool of bool
| Range of (int*int) list
| Tuple of value array
| Lambda of code
| Set of ValueSet.t (* this isn't allowed in my case since module is declared later*)
此外,我稍后在同一文件中为
ValueSet
声明了一个具体模块:

module ValueSet = Set.Make(struct type t = value let compare = Pervasives.compare end)
问题是
ValueSet
具有
value
作为elt类型,但是
value
可能是
ValueSet
所以我在尝试编译它时遇到了麻烦

所有这些声明都包含在一个名为
types.ml
的文件中(该文件有自己的接口
types.mli
,但没有任何
ValueSet
module decl,因为我不确定是否可能)


这个问题能以某种方式解决吗?

您可以使用递归模块。使用与递归集类型完全相同的示例来说明此语言功能。以下是相关摘录

递归模块定义的一个典型示例是:

module rec A : sig
                 type t = Leaf of string | Node of ASet.t
                 val compare: t -> t -> int
               end
             = struct
                 type t = Leaf of string | Node of ASet.t
                 let compare t1 t2 =
                   match (t1, t2) with
                     (Leaf s1, Leaf s2) -> Pervasives.compare s1 s2
                   | (Leaf _, Node _) -> 1
                   | (Node _, Leaf _) -> -1
                   | (Node n1, Node n2) -> ASet.compare n1 n2
               end
    and ASet : Set.S with type elt = A.t
             = Set.Make(A)
可提供以下规格:

module rec A : sig
                 type t = Leaf of string | Node of ASet.t
                 val compare: t -> t -> int
               end
    and ASet : Set.S with type elt = A.t

似乎我的OCaml编译器(3.11.0)还不支持它们。在任何情况下,在
types.ml
中使用这种递归声明都会强制使用
types.InnerTypes
types.ValueSet
这样的内部模块,这对ValueSet来说是可以的,但对另一个来说则不行。我想我正在慢慢地管理它,使它以某种方式工作。。如果我能让它工作的话,我可能会在短时间内接受你的答案:)OCaml从3.07开始就有了递归模块。