【发布时间】:2012-03-20 03:42:23
【问题描述】:
如果我在 OCaml 顶部循环中编程,并且我想使用来自 OCaml standard library 或 some other library 的包,我如何找出要加载的 .cma 文件?例如,在标准库中,String 在 str.cma 中,Big_int 在 nums.cma 中,因此文件名无法从模块名称或描述中辨别出来。
有没有一种简单的方法可以为模块查找正确的文件?
【问题讨论】:
标签: ocaml
如果我在 OCaml 顶部循环中编程,并且我想使用来自 OCaml standard library 或 some other library 的包,我如何找出要加载的 .cma 文件?例如,在标准库中,String 在 str.cma 中,Big_int 在 nums.cma 中,因此文件名无法从模块名称或描述中辨别出来。
有没有一种简单的方法可以为模块查找正确的文件?
【问题讨论】:
标签: ocaml
通常,给定一个 Ocaml 库 .cma,您可以使用 objinfo(又名 ocamlobjinfo,特别是在 Debian、Ubuntu 等上)获取它定义的模块。因此,给定库路径(/usr/lib/ocaml 等)和所花费的时间,应该可以在模块和 Ocaml 库之间构建映射。
【讨论】:
首先,您并不是真的想知道要加载哪个 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
NB 从模块名称到文件名的映射不是唯一的 - 例如SomeModule 可以用someModule.cmi 或SomeModule.cmi 表示(不太常见)。
【讨论】:
String(string 数据类型上的常用函数)不在 str.cma 中,它是 Str(用于操作正则表达式的函数)。
nums.cma 的名称也有类似的理由:它主要封装了模块 Num,这是不同“大数字”库(Nat、Big_int、Ratio)之上的一层。请注意,现在您可能想改用Zarith。
【讨论】:
正如 Po' Lazarus 所建议的,我使用ocamlobjinfo 来构建.cma 文件和定义的模块之间的映射,以便于参考。
bigarray.cma:
dbm.cma:
dynlink.cma:
graphics.cma:
nums.cma:
stdlib.cma
str.cma:
toplevellib.cma:
unix.cma:
【讨论】: