How did I want to split the code between src / Lib.hs and app / Main.hs in a new stack project?

I followed the stack guide and I got a new project setup (yay!).

The following file layout was generated:

. โ”œโ”€โ”€ app โ”‚  โ”œโ”€โ”€ Main.hs โ”œโ”€โ”€ .gitignore โ”œโ”€โ”€ LICENSE โ”œโ”€โ”€ helloworld.cabal โ”œโ”€โ”€ Setup.hs โ”œโ”€โ”€ src โ”‚  โ””โ”€โ”€ Lib.hs โ”œโ”€โ”€ stack.yaml โ””โ”€โ”€ test โ””โ”€โ”€ Spec.hs 

According to the Files section in helloworld ":

The application files /Main.hs, src / Lib.hs and test / Spec.hs are the Haskell source files that make up the actual functionality of our project (we will not dwell on them here).

I really would like them to stop there for a second, because I have no idea what the difference between app/Main.hs and src/Lib.hs should be. What code should I put where?

How should I split the code between app/ , src/ , app/Main.hs and src/Lib.hs ?

If I just write an application or just write a library, do I need both files / directories?

+6
source share
2 answers

This separation of modules between folders can be anything you want. The naive idea is that you paste almost all the logic into the Lib folder, and Main.hs simply imports the required parts of Lib , reads the command line arguments and starts the material. You can rename the app to executables and change the corresponding lines in the .cabal file. In fact, you can create an arbitrary file hierarchy.

In our project, we use a different, but very popular approach. And our file hierarchy looks like this:

 . |-- bench |-- src |-- exec1 |-- Main.hs |-- exec2 |-- Main.hs |-- SuperCoolLibraryName |-- LibModule1.hs |-- LibModule2.hs |-- test |-- Setup.hs 

And other stack.yaml , .cabal files, etc.

Actually, if you are writing an application, you can simply create one Main.hs file and put all the logic inside main . You will not believe it, but as a Haskell teacher, I saw this code from my students :( Although I do not suggest you write code in this way.

If you are writing a library, you do not need Main.hs and main files. You can look at a simple example, for example, this library (it allows you to automatically generate command-line options from data types): optparse-generic

PS Sorry for my English, I hope I helped you with your confusion.

+4
source

The main reason that he usually sets up, even for an application, is to write tests. Suppose you create a default stack project called foo , the test suite foo-test will depend on the foo library, as well as on foo-exe . If you have included all your functions in app/Main.hs , then these functions cannot be tested from the foo-test suite.

If you just play and donโ€™t care about the test suite, you can create your stack project on the simple template:

 $ stack new foo simple 

If you want to set up testing, I like tasty . You would modify your .cabal file .cabal this:

 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 

Then look in the example .

+2
source

All Articles