Setting up your Haskell development environment¶
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.
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
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.
- Via a minimal installer or the Haskell Platform
- Via Stack (recommended)
- Via Nix/NixOS
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 right
ghcversion for your project.
- Taking care of which Haskell libraries are known to compile/build with which
- 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
stacksaves 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):
bundlerfrom the Ruby world
virtualenvfrom the Python world
gvmfrom the Go world
yarnfrom 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
nano. There is stuff available - just lower
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¶
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
hiebinary (command-line tool) using the following steps (the last step
stack installis 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
hiebinary (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 the
hiecommand. You can exit it by pressing
$ 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 serverplugin (the correct plugin is the one authored by
Alan Zimmerman) => Click the
Restart your editor.
Note down the
resolverthat HIE is using (instructions given below):
For HIE & VSCode users
Next, open the
haskell-ide-enginedirectory (the one which you cloned above) and open the
stack.yamlfile. There may be multiple files like
stack-8.2.2.yaml. Ignore those extra files. You need the
stack.yamlfile. Note down the resolver (very first line of this file). You will need to use this in the next section.  For example, on my machine, following are the contents of
stack.yamland the resolver is
lts-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:
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)
Create a new file called Throwaway.hs in your project:
first-project/src/Throwaway.hs and make sure it has the following contents:
module Throwaway where addNumbers :: Int addNumbers = 1 + 2
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
Now, fire-up GHCi:
$ stack ghci Main Lib> :l Throwaway Main> addNumbers 3
Now, make some changes to Throwaway.hs, WITHOUT EXITING GHCi:
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
stack ghcifrom 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
- Run a function
- Change something in the function
- Reload the file via
:r(There is a difference in the behaviour of
:rthat 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:
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
cabaldoes 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
stackpulls 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.
|||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.|