Cabal projects
| cabal init | |
| The .cabal file | |
| Build and run | |
| Project layout |
cabal init
A real project starts with a directory and one command. Cabal asks a few questions and writes the skeleton:
mkdir todo && cd todo && cabal init
Package name? [default: todo] Package version? [default: 0.1.0.0] What does the package build: 1) executable ... Guessing dependencies...
Answer 1 for an executable, accept the defaults, and choose base as the only dependency for now.
The .cabal file
The generated todo.cabal is the project description. Four stanzas matter at this stage:
cabal-version: 3.0
name: todo
version: 0.1.0.0
executable todo
main-is: Main.hs
hs-source-dirs: app
build-depends: base >=4.18 && <5
default-language: Haskell2010
build-depends is the dependency list, and the version bounds are a promise about which versions your code was tested against. Keep them loose but present.
Build and run
Four commands cover the whole edit cycle. Cabal caches what it built, so the second run is fast:
cabal build
cabal run todo
cabal repl
ghci> :t main main :: IO ()
cabal repl loads the project modules with the right paths and dependencies, which is why it beats a bare ghci once the project has more than one file.
Project layout
The conventional layout separates the program from the library so that tests can import the logic without running main:
todo/ ├── app/Main.hs ├── src/Todo.hs ├── test/Spec.hs ├── todo.cabal └── cabal.project
The executable depends on the library and does nothing but parse
arguments and call it. That single decision is what makes the
capstone testable in lesson 49.
Next:
Dependencies
Article author: Arthur Isaev