如何拥有嵌套库?对沙丘等感到困惑

Ane*_*pic 10 ocaml ocaml-dune

我有一个 OCaml 项目使用dune

按照基本教程中的建议,我有一个目录结构,例如:

bin/
    cli.ml
    dune
lib/
    dune
    ...
    <various>.ml
Run Code Online (Sandbox Code Playgroud)

我的目录中的文件数量lib不断增加,我希望有另一个级别的命名空间。

我想要子目录,例如:

lib/
    utils/
        dune
        ...
        <various>.ml
    some_other_domain/
        dune
        ...
        <various>.ml
    dune
    ...
    <various>.ml
Run Code Online (Sandbox Code Playgroud)

我希望能够像这样打开它们Lib.Utils.Whatever

我想这一定是可能的吗?

我尝试dune在下面创建一个文件lib/utils

bin/
    cli.ml
    dune
lib/
    dune
    ...
    <various>.ml
Run Code Online (Sandbox Code Playgroud)

...但open Lib.Utils.Whatever似乎不起作用。

我找到了该subdir...但是如果我将其添加到lib/dune并定义utils为子目录library,那么我就不会得到命名空间...我必须open Utils这样做而不是open Lib.Utils

Lho*_*ooq 7

称它们为“嵌套库”实际上有点奇怪,因为您想用Lib.Utils.Whatever. Utils,这里是一个子模块Lib。如果对您有帮助的话,这是我能做的:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 suba\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 suba.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb.ml\n
Run Code Online (Sandbox Code Playgroud)\n

\n

bin/cli.ml

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 suba\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 suba.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb.ml\n
Run Code Online (Sandbox Code Playgroud)\n

bin/dune

\n
let () =\n  Lib.Suba.a ();\n  Lib.Subb.b ()\n
Run Code Online (Sandbox Code Playgroud)\n

lib/dune

\n
(executable\n (name cli)\n (libraries lib)\n)\n
Run Code Online (Sandbox Code Playgroud)\n

(如果您像这样包含模块,则必须将它们与这些确切的名称一起使用,获得控制权的另一种方法是添加以下文件并删除该行(modules suba subb)

\n

lib/lib.ml

\n
(include_subdirs unqualified)\n\n(library\n (name lib)\n  (modules suba subb)\n)\n
Run Code Online (Sandbox Code Playgroud)\n

(总结一下:

\n
    \n
  • 您的dune文件包含(modules suba subb)\n
      \n
    • 如果子目录包含多个文件,您需要将您正在使用的所有文件放入您的(modules ...)节中,否则编译器将无法使用它们
    • \n
    \n
  • \n
  • 或者一个lib.ml文件,其中应包含您要导出的每个模块module MyName = AModule(并且仅包含您要导出的模块)\n
      \n
    • 使用此解决方案,您不想导出的模块不需要显式包含在文件中lib.ml,编译器将在需要时使用它们\n)
    • \n
    \n
  • \n
\n

sub{a|b}/{a|b}.ml

\n
(* here you can give the name you want -- say A -- and use it in bin with Lib.A *)\nmodule Suba = Suba\nmodule Subb = Subb\n
Run Code Online (Sandbox Code Playgroud)\n

suba.mlsubb.ml用作 和 的子模块,lib可以与 一起使用,Lib.Suba.a()如您在cli.ml

\n
\n

请注意,这会禁止您为两个文件提供完全相同的名称,因为这些目录将在父目录中全部展平,因此您不能有类似的内容:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 suba\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n
Run Code Online (Sandbox Code Playgroud)\n

因为(include_subdirs unqualified)会让它看起来像

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n
Run Code Online (Sandbox Code Playgroud)\n

并且dune无法知道哪个lib.ml要使用哪个文件。

\n
\n

[编辑] 如果您想要每个库一个目录,您只需删除dune根目录下的文件lib并为每个子目录创建一个目录:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 suba\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 suba.ml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb.ml\n
Run Code Online (Sandbox Code Playgroud)\n

唯一的变化是:

\n

bin/cli.ml

\n
let {a|b} () = Format.eprintf "{A|B}@."\n
Run Code Online (Sandbox Code Playgroud)\n

bin/dune

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 suba\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subb\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n
Run Code Online (Sandbox Code Playgroud)\n

lib/dune已被删除

\n

lib/sub{a|b}/dune

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.ml\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib.ml\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib.ml\n
Run Code Online (Sandbox Code Playgroud)\n

在这种情况下,不同目录中的多个文件可以具有相同的名称。

\n