Functional programming 如何在OCaml文件中加载模块?

Functional programming 如何在OCaml文件中加载模块?,functional-programming,ocaml,Functional Programming,Ocaml,我希望在我的OCaml.ml文件中使用moduleStd 我试图加载“Std”,但编译器抱怨 如何在OCaml中加载模块?您必须首先编译要包含的模块,根据它向模块的编译命令提供编译文件的位置,然后在最终的编译命令行中提供 让我们考虑文件 fo/Meime.mL: let v = 1 open ModuleA let w = v 和文件bar/moduleB.ml: let v = 1 open ModuleA let w = v 命令: $ cd foo $ ocamlc -c modu

我希望在我的OCaml
.ml
文件中使用module
Std

我试图加载“Std”,但编译器抱怨


如何在OCaml中加载模块?

您必须首先编译要包含的模块,根据它向模块的编译命令提供编译文件的位置,然后在最终的编译命令行中提供

让我们考虑文件<代码> fo/Meime.mL<代码>:

let v = 1
open ModuleA
let w = v
和文件
bar/moduleB.ml

let v = 1
open ModuleA
let w = v
命令:

$ cd foo
$ ocamlc -c moduleA.ml
$ cd ..
将产生
moduleA.cmo
moduleA.cmi
。前者是模块的字节码对象(类似于本机对象文件中的
.o
文件,但包含字节码数据和文本),后者是字节码编译头,由自动生成的
.mli
文件生成。此字节码头是编译器编译依赖于
ModuleA
的文件所必需的

$ cd bar
$ ocamlc -I ../foo -c moduleB.ml
$ cd ..
将成功生成
moduleB.cmo
,这取决于
ModuleA
,因为上一个命令已成功,并且因为我们使用
-I
命令行参数指示编译器在何处查找依赖项,后跟第一个模块的路径

下面的最后一个命令将从两个模块生成字节码可执行文件:

$ ocamlc -I foo -I bar moduleA.cmo moduleB.cmo -o prog.byte
模块必须按该顺序提供,以便让编译器首先知道依赖关系。这次的
-I
参数指示在哪里可以找到
.cmo
文件


因此,在您的情况下,必须将
-I
用于正确的编译阶段,将
-I
(或
std.cma
,如果是库)用于第二阶段(链接阶段)。如果您可以在一个命令中组合这两个阶段(即,
ocamlc-I foo foo/moduleA.ml bar/moduleB.ml-o prog.byte
),并且如果
cmo
cmi
文件都在同一目录中,那么只有一个参数就足够了。

您必须首先编译希望包含的模块,根据模块的编译命令提供编译文件的位置,然后在最终的编译命令行中提供

让我们考虑文件<代码> fo/Meime.mL<代码>:

let v = 1
open ModuleA
let w = v
和文件
bar/moduleB.ml

let v = 1
open ModuleA
let w = v
命令:

$ cd foo
$ ocamlc -c moduleA.ml
$ cd ..
将产生
moduleA.cmo
moduleA.cmi
。前者是模块的字节码对象(类似于本机对象文件中的
.o
文件,但包含字节码数据和文本),后者是字节码编译头,由自动生成的
.mli
文件生成。此字节码头是编译器编译依赖于
ModuleA
的文件所必需的

$ cd bar
$ ocamlc -I ../foo -c moduleB.ml
$ cd ..
将成功生成
moduleB.cmo
,这取决于
ModuleA
,因为上一个命令已成功,并且因为我们使用
-I
命令行参数指示编译器在何处查找依赖项,后跟第一个模块的路径

下面的最后一个命令将从两个模块生成字节码可执行文件:

$ ocamlc -I foo -I bar moduleA.cmo moduleB.cmo -o prog.byte
模块必须按该顺序提供,以便让编译器首先知道依赖关系。这次的
-I
参数指示在哪里可以找到
.cmo
文件


因此,在您的情况下,必须将
-I
用于正确的编译阶段,将
-I
(或
std.cma
,如果是库)用于第二阶段(链接阶段)。如果可以在一个命令中组合这两个阶段(即
ocamlc-ifoo-foo/moduleA.ml bar/moduleB.ml-o prog.byte
),并且如果
cmo
cmi
文件都在同一目录中,那么只有一个参数就足够了。

指令并不真正用于编译项目。这是编译行的问题。那么如何使用
Std
module呢?尽管didierc提到使用
open
,但这被认为是不好的做法(本地上下文除外)。这是因为可以覆盖以前声明的函数。在答案的情况下,您应该调用,
ModuleA.v
。在复杂的代码中,您可以清楚地知道
v
的来源。
#
指令并不是真正用于编译项目的。这是编译行的问题。那么如何使用
Std
module呢?尽管didierc提到使用
open
,但这被认为是不好的做法(本地上下文除外)。这是因为可以覆盖以前声明的函数。在答案的情况下,您应该调用,
ModuleA.v
。它更清晰,在复杂的代码中,您确切地知道
v
的来源。