Jac*_*ack 6 recursion linker ocaml module cross-reference
参考链接如何在OCaml中工作?
例如,假设我有3个模块声明为
A.mlB.mlC.ml其中
A需要B和CB 需求 A我该如何进行编译?
由于订单是相关的,ocamlc或者ocamlopt我如何修复B和之间的交叉参考A?
我想首先他们都汇编成.cmo用ocamlc -c,然后链接所有的人都在一起,但自从与交换参数将刚刚从一个模块移动到另一个问题没有成功.
具体错误是:
错误:链接A.cmo时出错:引用未定义的全局`B'
(或者反之,如果我交换了args的顺序)
我认为这是一个简单的问题,但我无法解决它...提前感谢
您必须将模块组合到一个文件中并使它们递归.我不相信有两种方法可以从两个单独文件的编译过程中做到这一点.
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
Run Code Online (Sandbox Code Playgroud)
编辑:从您的评论,我猜你有解析器的类型定义和处理/操作同一文件中的类型的函数.我同意你的观点,这是有道理的.但是,就像你曾经历过的那样,如果该文件不仅仅是对类型进行操作而是调用解析器来生成数据,那么解析器将如何构建它呢?我的解决方案是将类型分成它自己的模块,并在执行操作的模块中打开该模块.
因此,您将拆分A为(A和A'),其中A'包含由其生成B和使用的类型A.你的依赖关系成了,
A需要A'和B与CB 需求 A'例如,我有一个解析器用于配置文件,我用它来启动我编写的任何应用程序.
Run Code Online (Sandbox Code Playgroud)ConfType --contains the type t Conf --calls parser, and contains helper functions for type ConfType.t ConfParser --for ocamlyacc ConfLexer --for ocamllex
所有这些的替代方案是使用多态变体.通过这种方式,您可以删除依赖项,因为它们是临时定义的.当然,解析器生成的类型可能与Conf中的类型不同,编译器无法帮助您解决错误.