为什么 OCaml 代码会出现这个编译错误?

Why is there this compilation error for OCaml code?

我目前正在测试 Facebook 的 Infer(开源)v0.17.0 并尝试通过命令 bash 文件从源代码构建它

$> ./build-infer.sh clang

但是,我在编译时遇到错误,具体错误是这样的。

[23:35:46][ 98156] Building clang plugin...
[      0s][ 98156] SUCCESS Building clang plugin
[23:35:46][ 98165] Building clang plugin OCaml interface...
[      0s][ 98165] SUCCESS Building clang plugin OCaml interface
[23:35:47][ 98205] Generating source dependencies...
[      0s][ 98205] SUCCESS Generating source dependencies
[23:35:47][ 98298] Building native(opt) Infer...
[*ERROR**][98298] *** ERROR 'Building native(opt) Infer'
[*ERROR**][98298] *** command: ' make INTERACTIVE=1 -C /home/roksui/Dev/dbtest/infer/src infer'
[*ERROR**][98298] *** CWD: '/home/roksui/Dev/dbtest'
[*ERROR**][98298] *** stdout:
[*ERROR**][98298] make[1]: Entering directory '/home/roksui/Dev/dbtest/infer/src'
[*ERROR**][98298] Makefile:122: recipe for target '/home/roksui/Dev/dbtest/infer/bin/infer.exe' failed
[*ERROR**][98298] make[1]: Leaving directory '/home/roksui/Dev/dbtest/infer/src'
[*ERROR**][98298] *** stderr:
[*ERROR**][98298] Entering directory '/home/roksui/Dev/dbtest/infer'
[*ERROR**][98298] File "src/base/Utils.ml", line 322, characters 4-13:
[*ERROR**][98298] 322 |     Unix.dup2 ~src ~dst:Unix.stderr () ;
[*ERROR**][98298]           ^^^^^^^^^
[*ERROR**][98298] Error: This function has type
[*ERROR**][98298]          src:IStdlib.IStd.Unix.File_descr.t ->
[*ERROR**][98298]          dst:IStdlib.IStd.Unix.File_descr.t -> unit
[*ERROR**][98298]        It is applied to too many arguments; maybe you forgot a `;'.
[*ERROR**][98298] make[1]: *** [/home/roksui/Dev/dbtest/infer/bin/infer.exe] Error 1

看来是函数Unix.dup2的参数太多的问题,所以我搜索了ml文件,下面是错误发生的代码片段。

let suppress_stderr2 f2 x1 x2 =
  let restore_stderr src =
    Unix.dup2 ~src ~dst:Unix.stderr () ;
    Unix.close src
  in
  let orig_stderr = Unix.dup Unix.stderr in
  Unix.dup2 ~src:(Lazy.force devnull) ~dst:Unix.stderr () ;
  let f () = f2 x1 x2 in
  let finally () = restore_stderr orig_stderr in
  protect ~f ~finally

据我所知,Unix.dup2 函数接受两个参数 src 和 dst。但是额外的单位参数 () 在这里发生了什么?

出现这个错误是因为我使用了错误版本的ocaml编译器吗?为什么会出现此错误?任何见解将不胜感激。谢谢。

Facebook Infer 使用 core 标准库替换 v0.14.x, which had a terminating unit argument。最新版本已经不行了。所以问题似乎是你安装了错误的版本。

编辑:实际上,我查看了Core 中的wrong docs, which despite being hosted at jane street and mentioning core several times in the URL, seems to actually be the documentation for the OCaml std lib Unix module. The latest version of Unix.dup2 仍然有可选和终止的unit 参数。这可能意味着您根本没有安装 Core。但无论哪种方式,您都需要返回并查看我认为的构建和先决条件说明。

终止参数 unit 通常在您的函数具有可选参数或仅标记参数时使用。由于带标签的参数可以按任何顺序应用,因此编译器无法知道没有可选参数的函数应用程序应该被视为部分应用还是完全应用。它将假定部分应用,因此在这种情况下可选参数实际上不是可选的。为了解决这个问题,通常使用未标记的 unit 参数来告诉编译器应该考虑完全应用该函数。

出于某种原因,可选参数已从 dup2 中删除,连同终止 unit 参数,因为不再需要它。