我试图在模块之间传递AST,我在主模块中写了下一句话:
let var = "value" in
.
.
let tree = Parse.parse_tree ~file:input input_text |> M1.f1 |> M2.f2
关键是,在M2.f2
中,我需要计算一个从Main
模块接收参数的函数。是否有一种方法将参数从一个模块传递到另一个模块?就像命令式编程中的"全局变量"一样?我读到我需要在Main.ml
中声明签名以共享数据类型或结构,但我无法理解如何使用它在模块之间传递变量。根据这个例子:https://ocaml.org/learn/tutorials/modules.html只需要使用模块名点加变量来引用var。
您可以使用由模块名和变量名组成的限定名引用在另一个模块中定义的值。例如,要引用模块Main
中定义的变量var
,可以编写Main.var
。OCaml中的每个编译单元(文件),隐式地定义了一个与文件同名的模块,除了它是大写的并且扩展名被丢弃,例如,如果你有一个名为foo.ml
的文件,它将隐式地定义一个模块Foo
,并且要引用该模块中定义的值,你需要用Foo.
作为前缀。默认情况下,模块中定义的所有值都是可见的,并且可以从其他模块中引用。您可以通过定义签名来隐藏值。如果您有一个由文件foo.ml
定义的隐式模块,您可以创建一个签名文件foo.mli
,该文件将声明哪些值是可见的。
当您有一个包含多个文件夹的复杂沙丘项目时,通常每个子文件夹定义一个不同的库。同一库中的模块可以通过名称直接相互引用。要引用另一个库中的模块,应该在模块名前加上该库的名称,例如Mylib.Foo.var
。查看文件夹中的dune
文件,该文件定义了library
定义的name
字段的库,例如
(library
(name mylib))
为了在其他库或程序中访问库mylib
的模块,您还需要将该库添加到库列表中。打开当前文件夹中的dune
文件,找到相应的executable
或library
定义和(libraries mylib)
,如果libraries
字段已经存在,则附加mylib
,例如
(executable hello_word
...
(libraries core mylib))
同样重要的是要知道,模块之间的循环依赖在OCaml中是不允许的。例如,如果您的主应用程序正在使用库mylib
,库mylib
在任何情况下都不能引用main
模块。因此,将值从主模块传递给库的唯一方法是将其作为参数传递给函数。