我是Ocaml的新手并尝试编写一些小型示例应用程序。我在Linux Ubuntu 10.04下使用ocamlc
版本3.11.2。我想编译两个文件:
a.ml
b.ml
文件b.ml
使用a.ml
中的定义。据我了解,我可以使用ocamlc -c
仅执行编译。当我有所有ocamlc
个文件将它们链接到可执行文件时,我可以最后一次调用.cmo
。此外,在编译使用另一个文件中的定义的文件时,我必须告诉编译器在哪个.cmi
文件中找到外部定义。
所以我的想法是使用:
ocamlc -i -c a.ml > a.mli
ocamlc -c a.mli b.ml
ocamlc -o b a.cmo b.cmo
第一步工作并生成文件a.mli
和a.cmo
,但在运行第二步时我得到了
File "b.ml", line 1, characters 28-31:
Error: Unbound value foo
其中foo
是a.ml
中定义并在b.ml
中调用的函数。
所以我的问题是:我如何单独编译每个源文件并指定要在命令行上导入的接口?我一直在查看文档,据我所知,我必须指定要包含的.mli
文件,但我不知道如何。
修改
这里有一些更多细节。文件a.ml
包含定义
let foo = 5;;
文件b.ml
包含表达式
print_string (string_of_int foo) ^ "\n";;
真实的例子比较大,但是对于这些文件,我已经有了上面报告的错误。
编辑2
我已编辑了文件b.ml
,并将foo
替换为A.foo
,这有效(foo在b.ml
中可见,即使我有另一个编译错误,这对我来说并不重要这个问题)。我想根据
.mli
文件更清晰
答案 0 :(得分:5)
如果您显示的代码不起作用会更清楚。正如克里斯托弗指出的那样,最可能的问题是你没有指定模块foo
所在的模块。你可以明确地指定模块,A.foo
。或者您可以open A
使用名称foo
。
对于一个小例子并不重要,但对于一个大项目,你应该注意不要过于自由地使用open
。你希望自由在你的模块中使用好的名字,如果你打开了太多的名字,好名字可能会相互冲突。
答案 1 :(得分:5)
首先解决unbound value
问题,正如Jeffrey的回答所解释的那样。
这是关于您正在使用的命令的评论。
通过几个步骤分解编译是理解正在发生的事情的好方法。
如果您想编写自己的a.mli
,最有可能隐藏模块A
的某些值,那么您的命令ocaml -i -c a.ml > a.mli
是获取此文件的第一个版本的好方法,然后编辑它。但如果您没有触摸a.mli
,那么您不需要生成它:您也可以直接输入
ocamlc -o foo a.ml b.ml
将生成a.cmo
,b.cmo
和exectuable foo
。
(它还会生成a.cmi
,这是a.mli
的编译版本,您可以通过发出ocamlc -c a.mli
来获得。同样,它也会生成b.cmi
)。< / p>
请注意,顺序很重要:您需要在命令行上a.ml
之前提供b.ml
。这样,在编译b.ml
时,编译器已经看到a.ml
并且知道在哪里找到模块A
。
更多评论:
A
的值可用,但名称不同A.foo
。 a.ml
的内容尚未复制粘贴到b.ml
中,而是A
中定义的模块a.ml
的值及其编译版本a.cmo
被访问过。A
中使用此模块b.ml
,则可以在b.ml
之前在命令行上传递以下任何内容:
a.mli
,将汇编为a.cmi
a.cmi
编入a.mli
a.cmi
a.ml
或其编译版本a.cmo
如果您不需要编写自己的a.mli
,即模块A
的默认界面是否适合您。 (此界面只是a.ml
)的每个值。