我已经处理一个设计问题已经有一段时间了,其中循环依赖是基本问题,我在优雅地解决它时遇到了一些问题。我来自 C,循环依赖既可能而且很容易解决。
以下是项目中感兴趣的文件的非常简化的图像:
ast.ml(实际上没有接口,我不太热衷于复制整个类型)
type loc = string * (int * int) * (int * int)
and id = string * loc
and decl =
| Decl_Func of decl_func
and decl_func = {
df_Name: id;
mutable df_SymTab: sym_tab option;
}
(* goes on for about 100 more types *)
符号表.mli
type t
type symbol =
| Sym_Func of Ast.decl_func
val lookup_by_id: Ast.id -> symbol
(以后还有更多文件要添加)
在 C 语言中,我只需将符号表设为指针,然后前向声明它。问题解决了。不幸的是,这在 OCaml 中是不可能的。
每个实现都非常大。这意味着我绝对不想让所有东西都成为递归模块,因为这意味着实现文件将是 10kloc 甚至更多,并且有大量不相关的代码(除了大递归类型)。
我将如何解决这个问题,同时仍然保持某种模块化设计?