您必须将模块组合到一个文件中并使它们成为递归的。我不相信有办法从两个单独文件的编译过程中做到这一点。
module rec A :
sig
val f : int -> int
val g : int -> int
end =
struct
let f x = (B.g x) + 1
let g x = x + 1
end
and B :
sig
val f : int -> int
val g : int -> int
end =
struct
let f x = (A.g x) + 1
let g x = x + 1
end
编辑:根据您的评论,我猜您有解析器的类型定义以及在同一文件中处理/操作该类型的函数。我同意你的观点,这是有道理的。但是就像您所经历的那样,如果该文件不仅要对类型进行操作,还要调用解析器来生成数据,那么解析器将如何构造它呢?我的解决方案是将类型分离到它自己的模块中,并在执行操作的模块中打开该模块。
因此,您将拆分A
为 (A
和A'
),其中A'
包含由 生成B
并在 中使用的类型A
。你的依赖变成了,
例如,我有一个配置文件解析器,用于启动我编写的任何应用程序。
ConfType --contains the type t
Conf --calls parser, and contains helper functions for type ConfType.t
ConfParser --for ocamlyacc
ConfLexer --for ocamllex
所有这些的替代方法是使用多态变体。通过这种方式,您可以删除依赖项,因为它们是临时定义的。当然,解析器生成的类型可能与 Conf 中的不同,编译器将无法帮助您解决错误。