我是怎么想在新的堆栈项目中将src/Lib.hs和app/Main.hs之间的代码分开?

Sun*_*rma 14 haskell haskell-stack

我正在关注堆栈指南,我得到了一个新的项目设置(耶!).

它生成了以下文件布局:

.
??? app
?   ??? Main.hs
??? .gitignore
??? LICENSE
??? helloworld.cabal
??? Setup.hs
??? src
?   ??? Lib.hs
??? stack.yaml
??? test
    ??? Spec.hs
Run Code Online (Sandbox Code Playgroud)

根据指南中的" helloworld中的文件 "部分:

app/Main.hs,src/Lib.hs和test/Spec.hs文件都是构成项目实际功能的Haskell源文件(我们在此不再赘述).

我真的希望他们暂时停留在那一秒钟,因为我不知道它之间的区别app/Main.hssrc/Lib.hs应该是什么.我应该把哪个代码放在哪里?

在哪些方面我应该划分之间的代码app/,src/,app/Main.hssrc/Lib.hs

如果我只是编写应用程序或只是编写库,我是否需要这两个文件/目录?

She*_*rsh 8

文件夹之间的模块分离可以是任何你想要的.天真的想法是你把几乎所有的逻辑放入Lib文件夹,Main.hs只需导入所需的部分Lib,读取命令行参数并运行东西.您可以重命名appexecutables和更改相应的行.cabal文件.实际上,您可以提出任意文件层次结构.

在我们的公司项目中,我们使用另一种非常流行的方法.我们的文件层次结构如下所示:

.
|-- bench
|-- src
    |-- exec1
        |-- Main.hs
    |-- exec2
        |-- Main.hs
    |-- SuperCoolLibraryName
        |-- LibModule1.hs
        |-- LibModule2.hs
|-- test
|-- Setup.hs
Run Code Online (Sandbox Code Playgroud)

stack.yaml,.cabal等文件.

实际上,如果您正在编写应用程序,您只需创建一个Main.hs文件并将所有逻辑放在main函数中.你不会相信,但作为一名Haskell讲​​师,我从学生那里看到了这样的代码:(虽然我不建议你以这种方式编写代码.

如果您正在编写库,那么您根本不需要Main.hs文件和main功能.您可以查看此库之类的简单示例(它允许您从数据类型自动生成命令行选项):optparse-generic

PS对不起我的英语,我希望我帮助你解决你的困惑.


Ste*_*haw 5

即使对于应用程序来说,通常也这样设置的主要原因是为了编写测试。假设您创建一个名为 的默认堆栈项目foo,测试套件foo-test将依赖于foo该库,foo-exe. 如果您要将所有函数放入app/Main.hs,那么这些函数无法从测试套件中进行测试foo-test

如果您只是玩玩并且不关心测试套件,您可以将您的堆栈项目基于模板simple

$ stack new foo simple
Run Code Online (Sandbox Code Playgroud)

如果您想设置测试,我喜欢tasty。您.cabal可以像这样修改您的文件:

test-suite foo-test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base
                     , foo
                     , tasty
                     , tasty-hunit
                     , tasty-quickcheck
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010
Run Code Online (Sandbox Code Playgroud)

然后看一下例子