【问题标题】:Specifying "Up The Tree" Haskell Modules指定“Up the Tree” Haskell 模块
【发布时间】:2013-10-09 13:21:07
【问题描述】:

我的理解是,在 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中,我们如何导入SomeModuleXYZ

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

【问题讨论】:

  • 在“分支”拥有模块是很常见的——例如在与 Foo/ 目录相同的目录中创建 Foo.hs
  • 另外,准确地说:模块的虚线句法表示在GHC中的磁盘上的逻辑结构。报告本身根本没有说明模块是如何存储在磁盘上的,竞争对手的实现可以选择做其他事情——拥有清单文件、使用数据库、将东西存储在云中......

标签: haskell module hierarchy


【解决方案1】:

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

如果您使用 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 下的模块将只编译一次。

这是这项技术的a real-life example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-20
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    相关资源
    最近更新 更多