【问题标题】:What is the Haskell syntax to import modules in subdirectories?在子目录中导入模块的 Haskell 语法是什么?
【发布时间】:2011-02-17 21:09:17
【问题描述】:

Haskell 在另一个目录中导入模块的语法是什么?

我刚开始使用 Haskell,想练习用 HUnit 编写简单的函数 TDD 风格。不过,我无法弄清楚如何构建我的文件。 HUnit 附带的示例似乎是一个平面目录结构。

我想将我的测试和 HUnit 代码放在与我的实际代码不同的文件夹中。我将不胜感激一个快速示例导入语句和关于如何构建我的文件的建议。

如果重要的话,我现在正在使用 GHCi 和 NotePad++ 进行编码。

【问题讨论】:

标签: haskell hunit


【解决方案1】:

您实际上并没有从 Haskell 源代码中执行此操作;相反,您告诉编译器在哪里查找。通常的方法是在 .cabal 文件中。有关详细信息,请参阅the cabal user guide。您需要“hs-source-dirs”参数。

或者,您可以将路径直接传递给编译器。但是,Cabal 是更好的方法。

“hs-source-dirs”参数中的每个路径名指定模块层次结构的根。基本上,如果您导入一个名为“Data.Foo.Bar”的模块,那么编译器会在“hs-source-dirs”给定的每个目录中查找具有相对路径名“Data/Foo/Bar.hs”的文件并导入第一个它找到了一个。

【讨论】:

  • 谢谢,保罗。这很有帮助。我当然看过很多关于 Cabal 的讨论,但我不确定这是否是简单项目的最佳选择。和 Linux 一样,Haskell 很有趣,但大多数人在 500 级“解释”东西,并假设你已经有很多初学者没有的背景。我很欣赏它的清晰度。
  • 是否可以从不一定在同一个包中的硬编码目录导入模块?
  • @schulermine 如果您将路径放在hs-source-dirs 中,那么根据定义它们将成为包的一部分;它们被 cabal build 跟踪,被 cabal sdist 捆绑等。如果您不将它们视为包的一部分以进行版本控制,那么您将陷入混乱。在这种情况下,最好的办法是将其他目录制作成一个或多个包,然后将包路径放入stack.yamlextra-deps字段docs.haskellstack.org/en/stable/yaml_configuration
【解决方案2】:

Paul 的answer 是正确的,但我只是想扩展将路径直接传递给编译器的想法,以获得快速简便的解决方案,主要用于运行带有runhaskellrunghc 的脚本。

您需要做的就是将-i 标志传递给编译器,并使用冒号分隔的目录列表。然后编译器将检查这些目录中导入模块的源文件。

所以,例如,如果你有这样的目录结构:

home/
|-- user/
    |-- haskell/
        |-- Module1.hs
        |-- foo/
            |-- Module2.hs

您希望Module2 能够导入Module1,然后在Module2.hs 中照常添加您的导入语句:

import Module1

然后当你使用runhaskell 执行Module2.hs 时,你会像这样运行它:

$ cd /home/user/haskell/foo
$ runhaskell -i/home/user/haskell Module2.hs

参考:

【讨论】:

  • 感谢您的参考链接,我花了很长时间才找到它,因为它找到了这个答案。 runhaskell --help 通过在用法中显示 [runghc flags] [GHC flags] 来平底船,runghc --help 说...完全相同。最后ghc --show-options 向我们展示了-i,但在CLI 上没有描述。最终必须访问您引用的网页。对于像 OP 的情况这样的早期/简单测试中必须是非常常见的情况似乎是迂回的,但我想这就是为什么 Cabal 是下一个进步步骤。
  • 上述参考文献中的搜索路径如何与downloads.haskell.org/~ghc/7.0.3/docs/html/users_guide/… 相关联?是一样的吗?
猜你喜欢
  • 2018-11-25
  • 2022-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多