主模块应该放在一个惯用的Haskell项目中?

时间:2016-04-30 00:50:01

标签: haskell

根据Structure of a Haskell project的维基百科页面,惯用的haskell项目的src文件夹如下所示:

src/           -- For keeping the sourcecode
    Main.lhs     -- The main-module
    App/         -- Use hierarchical modules
      ...
      Win32/     -- For system dependent stuff
      Unix/
    cbits/       -- For C code to be linked to the haskell program

问题:

  1. 我假设Main.lhs是该计划的主要入口点。这样,我的意思是它包含main方法,该方法为某些类型IO (a)返回类型a的值。是这种情况吗?

  2. .lhsMain.lhs扩展名的含义是什么?为什么不称它为Main.hs

  3. 我在GitHub上看了一些其他流行的Haskell项目,他们似乎并没有密切关注这个结构。这真的是组织Haskell项目的惯用方法吗?

1 个答案:

答案 0 :(得分:9)

1

是。 The Haskell specification has a paragraph on this topic,你几乎逐字复制语言。

2

.lhs表示它是literate Haskell file。在常规的Haskell中,必须将注释标记为特殊注释,并且代码是默认的&#39 ;;在有文化的Haskell中,恰恰相反:代码必须标记为默认值,注释是默认值。'正如Knuth所说,"主要思想是将程序视为与人类的沟通,而不是作为计算机的一组指令。"

3

没有事实上的方法来组织Haskell项目。我认为有几种粗糙的无定形思想流派:

  • Blob。将所有内容放入一个目录中,并将Main.hs作为入口点。这对于一次性脚本和小项目非常有用。它使进口变得容易。您只需包含目录中的import FooFoo.hs

  • Blob With Folders。随着时间的推移,你会发现这个和那个模块作为子模块一起存在,所以这些和那些都是如此。您现在可以创建一个src/目录并将所有文件丢弃。此时你可能会开始像这样组织:

    /
     src/
       • Main.hs
       • Types.hs
       Types/
         • Internal.hs
         • Gadgets.hs
         • Geegaws.hs
     • project.cabal
     • README.md
    

    我们有一个Types模块,可以重新导出Types.*中的所有内容,以便您import Types可以获取所有内容,或者,如果您愿意,可以import Types.Internal或{{ 1}}导入点菜import Types.Gadgets的子模块。

  • 大图书馆,微小的可执行文件。如果使用Cabal或Stack,则可以设置库目标,然后设置可执行目标,该目标取决于库目标。 Types和可能的支持模块存在于可执行文件中,它们从库中导入代码。这是测试的理想选择,因为测试是一个单独的目标,也可以依赖于库。如果您希望项目发布其他可执行目标(大型系统的典型代表),您也可以使用它。您的结构可能如下所示:

    Main.hs

两者之间有各种各样的选择。 / lib/ Types/ • Internal.hs • Gadgets.hs • Geegaws.hs Types.hs src/ • Main.hs • Utils.hs • project.cabal • README.md lib/命名非常惯用。我猜它来自大型C系列项目(特别是GNU项目)倾向于命名的方式。 src/似乎是一个有趣的名称,每个人都集体选择用于包含代码的目录,该代码将被外部函数接口到Haskell代码中。可以偏离那篇wiki文章,我猜是外卖。

如果您install Stack,您可以创建一个目录并运行cbits/。堆栈附带默认目录结构(您可以自定义或完全关闭)。可能对比较和对比很有用。