如果我在OCaml toploop中进行编程,并且我想使用OCaml standard library或some other library中的包,我如何找出要加载的.cma文件?例如,在标准库中,String
位于str.cma
,Big_int
位于nums.cma
,因此文件名无法从模块名称或说明中辨别出来。
有没有一种简单的方法可以查找模块的正确文件?
答案 0 :(得分:6)
通常情况下,给定Ocaml库.cma
,您可以使用objinfo
(a.k.a。ocamlobjinfo
获取其定义的模块,特别是在Debian,Ubuntu上,...)。因此,给定库路径(/ usr / lib / ocaml等)和花费时间,应该可以构建模块和Ocaml库之间的映射。
答案 1 :(得分:4)
首先,你真的不想知道要加载哪个cma,而是想知道通过ocamlfind加载哪个包。接下来要注意的是,ocaml编译器需要执行相同的操作来编译项目 - 即通过源代码中引用的模块的名称找到该模块的编译接口。所以让我们模仿那种行为。编译器从命令行获取包含路径,但我们必须搜索所有可能的包含路径。所以我们走了:
for i in $(ocamlfind list | cut -d ' ' -f 1) ; do
if [ -r $(ocamlfind query $i)/XXX.cmi ] ; then
echo $i; break;
fi ;
done
或
ocamlfind printconf path | xargs -n1 -I/ find / -name XXX.cmi
注意从模块名称到文件名的映射不是唯一的 - 例如SomeModule
可以someModule.cmi
或SomeModule.cmi
(不太常见)来表示。
答案 2 :(得分:2)
String
(string
数据类型上的常用函数)不在str.cma
中,它是Str
(操作正则表达式的函数)。
nums.cma
名称有类似的理由:它主要封装模块Num
,它是不同“大数字”库(Nat
,{{1 },Big_int
)。请注意,现在您可能想要使用Zarith。
答案 3 :(得分:1)
我从来没有注意到这个问题,但你是对的,你不能从模块的名称中说出任何东西。由于我通常必须首先阅读文档,因此我总是从docs获取信息(在每个部分的开头列出标准模块)。
suaver解决方案是使用GODI及其相关的findlib
机制,看起来它解决了这个问题和许多其他问题。特别是,它不仅仅扩展到OCaml发行版附带的模块。
答案 4 :(得分:1)
正如Po'Lazarus建议的那样,我使用ocamlobjinfo
来构建.cma
文件和定义的模块之间的映射,以便于参考。
bigarray.cma
:
dbm.cma
:
dynlink.cma
:
graphics.cma
:
nums.cma
:
stdlib.cma
str.cma
:
toplevellib.cma
:
unix.cma
: