5

我的理解是,在 Haskell 中,模块的点语法表示磁盘上的逻辑结构。所以,如果我们有这样的结构:

Main.hs
Foo/
  Bar.hs    -- exports "Bar"
  Quux.hs   -- exports "Quux"

...然后在我们的 中Main.hs,我们可以这样做:

import Foo.Bar
import Foo.Quux

(我假设我们只能在文件系统的叶节点上拥有模块。例如,在上面,我们也无法拥有Foo模块。)

在此示例中,我们正在遍历树。如果我们想上去怎么办?

lib/
  SomeModule.hs
  XYZ.hs
src/
  Main.hs

也就是说,在 中Main.hs,我们如何导入SomeModuleor XYZ

也许这不会是常见的情况Main,但是模块间的依赖关系呢?他们可能合法地需要引用“表亲”节点。

4

1 回答 1

7

只需使用模块的完全限定名称,并使用该选项告诉 GHC 在哪里可以找到模块层次结构的根-i。在您的示例中,这意味着您应该使用import XYZinMain.hs来导入模块和命令ghc -i../src --make Main.hs来编译您的程序。如果您需要编译相互递归的模块,请查看 GHC 手册的这一部分

如果您使用 Cabal 构建您的包,您可以将模块分组到lib一个库中,然后将该库作为您的可执行文件的依赖项。您将具有以下目录结构:

some-package.cabal
lib/
  XYZ.hs
src/
  Main.hs

文件的相关部分some-package.cabal如下所示:

Name: some-package
Version: 1.0
...
Library
    ...
    Exposed-modules: XYZ
    Hs-source-dirs:  lib
    ...
Executable some-executable
    ...
    build-depends: some-package == 1.0
    ...
...

如果您的包包含测试或基准套件,这将特别有用,因为下面的模块lib将只编译一次。

这是该技术的真实示例

于 2013-10-09T13:58:05.820 回答