One of the most frequently asked Haskell beginner questions in recent years is:
"Stack or cabal?"
I will helpfully not answer this question. Instead I will hope to eliminate the confusion that many of the askers seem to have about the various different things named "cabal" and how they relate to each other and stack.
So, how many things named "cabal" do we have? We have:
CABAL (the spec)
CABAL is the Common Architecture for Building Applications & Libraries. It's a specification for defining how Haskell applications and libraries should be built, defining dependencies, etc.
.cabal(the file format)The file format used to write down the aforementioned definitions for a specific package.
Cabal (the library)
The library implementing the above specification and file format.
cabal(the executable)The
cabalexecutable, more accurately namedcabal-install, is a commandline tool that uses Cabal (the library) to resolve dependencies from Hackage and build packages.
Stack is a replacement for cabal-install, i.e. the cabal executable.
The stack commandline tool, like cabal-install is a tool that uses
Cabal (the library) to resolve dependencies and build packages. The main
difference between cabal-install and stack is how they resolve
dependencies.
So, what do cabal-install and stack do differently?
cabal-install looks at the declared version ranges of a package in the
.cabal file and using the available versions on Hackage it computes a build
plan satisfying the version constraints, then compiles using this build plan.
stack on the other hand uses "resolvers". A resolver is a snapshot of
various package versions on Stackage and dependencies are resolved by "just use
the exact version specified by the resolver".
It is possible to make stack resolve things dynamically [1] as
cabal-install and vice versa, you can create snapshots (freeze files) using
cabal-install to accomplish what stack does.
Honestly, at this point I don't think there is much difference, use whichever
tool best fits your workflow. The only real strong opinion I have is that you
should avoid Stack's (optional) use of hpack at all costs.
hpack is a tool that generates .cabal files from package.yaml. In
the past there were some (in my personal opinion, weak) reasons for using
package.yaml, but those are nowadays possible in .cabal too.
package.yaml does not support all CABAL features and requires all your
potential users to install extra tooling. The .cabal format is understood
by both cabal-install and stack without extra tools, so everyone can
just use/contribute with their preferred tools.
| [1] | As of Stack 2.x this functionality has been dropped from Stack and so this is no longer possible. |
This is not a complete guide and is lacking the following information, IMO: