For this class, we recommend you use the new Stack Haskell build system. You will see many references to Cabal and
cabal-install on the Internet for Haskell projects. This document tries to quickly explain the situation.
Our motivation for recommending Stack is that we believe it is easier for beginners to work with, particularly as it manages the version of GHC used so that you aren't reliant on your OS package manager.
We will be using
GHC 7.10 throughout this course.
Stack is a build system for Haskell that aims to give you extremely reproducible builds. To do this, it manages (and freezes) all your dependencies and the version of GHC being used for your project.
Stack is backed by the Stackage package system. Stackage uses the concept of 'snapshots', where all packages part of the same snapshot are meant to be compatible with each other. When installing a new package, you don't choose which version to install, instead when starting a project using Stack, you choose which Stackage snapshot to use. After that, all package versions are fixed, determined upstream by Stackage's snapshot mechanism.
Stack vs Cabal
Cabal is the package description format for Haskell. It describes what a package is and how packages interact with the language. It also provides common infrastructure for building and distributing packages.
Traditionally, Haskell programmers used a tool called
cabal-install that knows how to build a Cabal package.
cabal-install also interacts with a package hosting website, Hackage, for retrieving dependencies during the build process.
Each time a client of
cabal-install configured a package to prepare it for building or installation,
cabal-install would perform dependency resolution, resolving which version of packages A, B and C to use, such that all packages chosen are compatible with each other and all dependencies are satisfied. This works, but led to a problem known as 'cabal-hell' (similar to DLL-hell on Windows), where
cabal-install would fail to find a way to solve the dependency problem. This was particularly bad due to the use a single global package installation location, meaning all projects had to have compatible versions of packages.
cabal-install later adopted a 'sandbox' strategy where a project could install dependencies local to the project, which helps greatly.
cabal-install doesn't do a great job of giving developers reproducible builds. It may resolve package A to version 1.0 on one developers machine, and resolve package A to version 1.1 on a different developers machine if run at different times. It also doesn't manage GHC itself, considering that out of scope.
Stack and it's backing website, Stackage, instead solve this problem globally and once for everyone. They create a set of packages called a 'snapshot' where they try to guarantee that all packages part of a snapshot are compatible with each other and have all their dependencies contained in the snapshot. A project using Stack simply declares the snapshot they are using, and no dependency resolution needs to be performed. Stack also manages the version of GHC used as part of a snapshot.
Stack in Relation to Cabal
Stack doesn't replace Cabal, but does replace
cabal-install. It also doesn't replace Hackage, but provides 'snapshots' of it through Stackage.
See stack documentation, but we present the cliffs notes below.
Apple OS X
Probably the easiest way to install is using homebrew:
brew install haskell-stack
Stack is only available in AUR at this moment. You'll likely need the following two packages:
For Ubuntu 15.10:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 575159689BEFB442 echo 'deb http://download.fpcomplete.com/ubuntu wily main' |sudo tee /etc/apt/sources.list.d/fpco.list sudo apt-get update && sudo apt-get install stack -y
First, configure some defaults:
$ vim ~/.stack/config.yaml
This file should look something like:
templates: params: author-email: email@example.com author-name: Richard Lloyd copyright: Richard Lloyd github-username: rlloyd category: web
You can override these defaults on the command line:
stack new proj -p "category: testing"
stack new my-project cd my-project stack setup stack build stack exec my-project-exe
You can also load your project in GHCi (A Haskell REPL):
Or run your test suite: