OCaml 如何修复模块名称冲突

Gre*_*bet 8 ocaml namespaces

制作顶层时,模块名称不允许与内部编译器库冲突。

修复此类模块名称冲突的策略有哪些?

理想情况下,是否可以传递一些参数来ocamlc指示它“破坏”所有模块的名称以使用像 这样的自定义前缀MyProject_?(从 OCaml ABI 的角度来看,并不是字面上改变源文件)

完整示例如下:

Sqrt.ml包含

let sqrt x = x ** 0.5
Run Code Online (Sandbox Code Playgroud)

Sqrt.mli包含

val sqrt : float -> float
Run Code Online (Sandbox Code Playgroud)

mktop包含

#!/bin/bash

ocamlc -c Sqrt.mli -o Sqrt.cmi 
ocamlc -c Sqrt.ml  -o Sqrt.cmo

ocamlmktop -o sqrt_toplevel Sqrt.cmo
Run Code Online (Sandbox Code Playgroud)

我可以生成一个包含我想要的函数的顶层。

% ./sqrt_toplevel
        OCaml version 4.04.0

# Sqrt.sqrt 4.5;;
- : float = 2.12132034355964239
Run Code Online (Sandbox Code Playgroud)

如果我通过更改文件名将Sqrt模块重命名为Parse,则该名称与内部库冲突,并且顶层无法链接。

mktop就是现在

#!/bin/bash

ocamlc -c Parse.mli -o Parse.cmi 
ocamlc -c Parse.ml  -o Parse.cmo

ocamlmktop -o parse_toplevel Parse.cmo
Run Code Online (Sandbox Code Playgroud)

其他文件只需重命名为Parse.mlParse.mli

如果这样做,我会遇到与编译器库的命名冲突。

% ./mktop |& sed -e s:"$HOME":~:
File "Parse.cmo", line 1:
Warning 31: files Parse.cmo and ~/.opam/4.04.0/lib/ocaml/compiler-libs/ocamlcommon.cma(Parse) both define a module named Parse
File "_none_", line 1:
Error: Some fatal warnings were triggered (1 occurrences)
Exit 2
Run Code Online (Sandbox Code Playgroud)

Jef*_*eld 4

除了使用与内部模块不冲突的名称之外,我没有看到有记录的方法可以避免此问题。

以下是列出所有禁止名称的 Unix 命令,至少是这样的:

$ cd ~/.opam/4.04.0/lib/ocaml/compiler-libs
$ ocamlobjinfo ocamlbytecomp.cma ocamlcommon.cma ocamltoplevel.cma |
    awk '/^Unit name:/ { print $3}' | sort
Run Code Online (Sandbox Code Playgroud)

对我来说(现在使用 OCaml 4.03.0)有 96 个禁止名称。我写了一个脚本来验证所有 96 个确实是被禁止的。

作为附带评论,尽管报告了错误,但实际上还是生成了顶层。而且,经过快速测试,它似乎有效。该函数Parse.sqrt(例如)存在并计算正确的答案。但可能有些问题我只是没有遇到过。