Setting up your Haskell development environment¶
Pre-requisities¶
Use Linux or Mac. Do not waste time with Haskell on Windows - you may be able to make some progress initially, but you will run into weird errors later while bulding certain packages, or while building binaries. You have been warned.
Make sure you have a lot of RAM and an SSD. Serious Haskell projects (not textbook problems) are memory-guzzlers during development & compilation. Plus, if you’re like me, you will have 50 browser tabs open, as well. So, it won’t be long before your system starts swapping, which is why it’s better to have an SSD along with a lot of RAM. For serious Haskell development, we recommend at least 10 GB of RAM and at least 256 GB SSD. For text-book practice, you can probably get away with 4GB of RAM and an HDD.
Attention
Call for contribution
- Screen-recording of installing Stack & Spacemacs + Intero along with the first GHCi session
- Screen-recording of installing Stack & VSCode + HIE along with the first GHCi session
Installing Haskell¶
There are currently four ways to install Haskell! Yes, I know that’s crazy. Here’s what they are:
- Via your OS’ native package manager, i.e.
apt-get
, orhomebrew
, oryum
- Via a minimal installer or the Haskell Platform
- Via Stack (recommended)
- Via Nix/NixOS
Important
Recommendation
Out of the four methods listed above, only Stack is recommended for maintaining your sanity. So, head over to Stack’s Get Started page and follow only the first step, titled “Download Haskell Stack” for your OS. The other steps given on that page are covered in greater detail below.
Quick primer on Stack¶
stack
solves the following problems:
- Having different versions of the Haskell compiler (i.e.
ghc
) available on your machine without messing things up, and using the rightghc
version for your project. - Taking care of which Haskell libraries are known to compile/build with which
version of
ghc
. - Taking care of the dependency graph of libraries, so that all the libraries
that your project depends on, compile successfully without you having to
manually specify the version of each library. Basically
stack
saves you from the dependency hell problem.
In a sense stack is similar to the following tools from other ecosystems, which attempt to solve some, or all, of the same problems (but they may have solved them in a different manner):
rvm
andbundler
from the Ruby worldvirtualenv
from the Python worldgvm
from the Go worldnvm
oryarn
from the NodeJS world
Installing an editor¶
If you are used to tools like Eclipse/IntelliJ from the Java world, or Visual
Studio from the Microsoft world, you are in for a rude shock when it comes to
IDEs in Haskell. Firstly, there is no industrial-grade [I]ntegrated
[D]evelopment [E]nvironment for Haskell - so you can stop looking for it.
Secondly, as of Dec 2017, various Haskell editor plugins, don’t work as well
as they should. But, don’t worry - all is not lost - you won’t have to resort to
writing Haskell in ed
or nano
. There is stuff available - just lower
your expectations.
Here are two options that are known to work well:
- Spacemacs with intero - If you are comfortable with the Emacs editor, this should be your preferred choice.
- VS Code with HIE: Haskell IDE Engine - If you are comfortable with editors like Sublime, Atom, or VSCode itself, this should be your preferred choice. Please follow the instructions at Installing VSCode & HIE
Installing VSCode & HIE¶
Note
If you choose to use VSCode + HIE here are the installation instructions. You may skip this sub-section if you plan on using any other editor. Please comment/annotate if these instructions do not work for you.
Install the VSCode editor by downloading it from here
Install the
hie
binary (command-line tool) using the following steps (the last stepstack install
is going to take a lot of time - be patient).$ git clone https://github.com/haskell/haskell-ide-engine $ cd haskell-ide-engine $ stack install
Ensure that the
hie
binary (command-line tool) has installed successfully by going through the following steps. Ensure that you see output similar to what is shown above after you run thehie
command. You can exit it by pressingCtr+c
$ cd ~ $ hie 2017-12-14 10:44:42.963071 [ThreadId 4] - Setting home directory:/Users/saurabhnanda 2017-12-14 10:44:42.964856 [ThreadId 4] - run entered for HIE Version 0.1.0.0, Git revision ab3cb3e62605625128769d8553646cc4f01db6d1 (1129 commits) x86_64 2017-12-14 10:44:42.966338 [ThreadId 4] - Current directory:/Users/saurabhnanda
Open the VSCode editor and go the the “Extensions” tab, also known as the “plugin marketplace” => search for the
haskell language server
plugin (the correct plugin is the one authored byAlan Zimmerman
) => Click theinstall
button.Restart your editor.
Note down the
resolver
that HIE is using (instructions given below):Warning
For HIE & VSCode users
Next, open the
haskell-ide-engine
directory (the one which you cloned above) and open thestack.yaml
file. There may be multiple files likestack-8.2.1.yml
orstack-8.2.2.yaml
. Ignore those extra files. You need thestack.yaml
file. Note down the resolver (very first line of this file). You will need to use this in the next section. [1] For example, on my machine, following are the contents ofstack.yaml
and the resolver islts-9.14
. It may be different on your machine!resolver: lts-9.14 packages: - . - hie-apply-refact - hie-base - hie-build-plugin - hie-eg-plugin-async - hie-example-plugin2 # # and more lines will follow #
Get used to GHCi before you start¶
GHCi is the interactive coding environment for Haskell (also known as a REPL). You will be spending a lot of time in it. It comes wth a complete user-manual that you can refer to when you need to do more advanced stuff, but, for now, here’s some basic stuff that you’ll need to know.
Setup your first throw-away project:
Warning
For VSCode & HIE users
In the command given below, make sure you use the correct LTS version as mentioned in hieWarning
$ stack new --resolver=lts-9.14 first-project
$ cd first-project
$ stack setup
The last command stack setup
may take forever, becuase it will probably
download the GHC compiler and a bunch of core/base libraries. Also, it’s going
to take a shitload of disk-space (about 2GB+). Keep some covfefe (or beer)
handy.
Create a new file called Throwaway.hs in your project:
Open first-project/src/Throwaway.hs
and make sure it has the following contents:
module Throwaway where
addNumbers :: Int
addNumbers = 1 + 2
Important
Please take care of the case. In Haskell, modules are named with
CamelCase. The name of the module and the name of the file sould be the
same, for example, in this case the module is called Throwaway
and the
file is called Throwaway.hs
Now, fire-up GHCi:
$ stack ghci
Main Lib> :l Throwaway
Main> addNumbers
3
Now, make some changes to Throwaway.hs, WITHOUT EXITING GHCi:
Note
Do not exit GHCi
module Throwaway where
addNumbers :: Int
addNumbers = 10 + 20
Next, reload these changes in GHCI:
Main> :r
Main> addNumbers
30
That’s the most basic development workflow to follow:
- Always start
ghci
withstack ghci
from within your project directory. This will ensure that the correct version of the compiler is used and that your GHCi is aware of the files in your project and the packages that your project depends on. - Load a file in GHCi via
:l
- Run a function
- Change something in the function
- Reload the file via
:r
(There is a difference in the behaviour of:l
and:r
that you may read about, if you are interested.) - Re-run the function
Make sure you are reading the correct docs¶
You will find yourself referring to API documentation very often. However, do not search for the package names on Google and start reading docs from there. You will end-up in a world of pain without even realising it. Google doesn’t know which version of the package you’re using, and from a first-hand experience, things change a lot between versions.
So, here’s what you should do:
- Check which LTS/resolver you are on – it’ll be the very first setting in your
project’s
stack.yaml
file. - Go to the Stackage homepage and find the listing page for your LTS/resolver. For example, here’s the listing for lts-9.17
- Search for documentation and packages only from this page
Hackage vs Stackage & Cabal vs Stack¶
Strangely, Haskell has two widely used package repositories. Here is how they are conceptually different and why both exist:
- Hackage is the original package repository. This is where authors upload their packages to share them with the world.
- Stackage pulls specific versions of specific packages from Hackage and divides them into “sets” known as “snapshots”. Each snapshot contains only a single version of any package with a guarantee that all the packages in a given snapshot will successfully build when included in a project. That is, you will not get a dependency hell when your project depends on 5 packages from the same Stackage snapshot. (If you go to a snapshot/LTS’ listing page you can verify that there is only one version of each package listed there. On the other hand, if you check the same package on Hackage, you will see all versions of the package listed there).
- Hackage has way more packages than Stackage, because, not every author adds their package to the Stackage snapshot. This is probably because, every time a new LTS/snapshot is released, package-authors have to do some extra work to maintain the “no dependeny-hell guaranteee”. However, most popular/important packages have already been added to Stackage, so you won’t be missing any packages till you start doing advanced Haskell stuff.
- The command-line tool called
cabal
does not know about Stackage and pulls packages directly from Hackage. Also, cabal+Hackage do not give this “no dependency-hell guarantee” that stack+Stackage works very hard to maintain. - The command-line tool called
stack
pulls packages from Stackage, by default. Having said that, it can pull packages from Hackage if a particular package is not available in its snapshot (but this requires a few extra lines of config).
Finally, lot of cabal/Hackage lovers hate stack/Stackage and vice-versa. If you are in the mood for some gossip you can search the interwebs and read some flamewars. One hopes, that at some point in the future, the best parts of stack/Stackage and cabal/Hackage can be merged to build a unified, kickass build-tool. Till that day comes, just use Stack.
[1] | Strictly speaking, your project and HIE need to be using the same version of GHC, not necessarily the same LTS. However, for newbies, we recommend simply using the same LTS because it is simpler and is guaranteed to work. |