Table of Contents
I usually don’t write tutorials on using stuff but since I started to learn Haskell I found it hard to find a simple tutorial on how get started on a simple project. So, to help others and to save the pain for future me, I decided to write this tutorial.
So what’s the stack?
Okay, so you decided to give into functional programming and tried to give Haskell a go but you see a lot of conflicting information on the tools for writing Haskell code. The compiler is supposed to be GHC so… do you install it? Well yes, but no. While GHC is the compiler but you need a build tool to manage your project and dependencies.
As Haskell is an old language used in production for a while now, applications need specific versions of packages, and the compiler itself. So, you need a tool to manage all of this for you.
Cabal or more specifically Cabal-install is
the official build tool for Haskell. Both Cabal-install and Stack are frontends
to the Cabal library. Cabal-install looks at the dependencies specified in its
.cabal file and uses a dependency solver to figure out a set of packages and
package versions that satisfy it in the Hackage3 repository.
Stack however, is a bit newer and tries to solve some of the problems with
Cabal. It uses the resolver field in the
stack.yaml file to specify a snapshot
of the Hackage repository. This snapshot is a set of packages and package
versions that are known to work together. This means that you don’t have to
worry about dependency conflicts.
I use Stack because it’s newer and I find it easier to work with
Installing the tools
So, let’s get started, download the latest stack version and start coding. Wrong! You thought it’s going to be that easy? Well, get used to it being hard. We’ll use GHCup4 to get the the recommended versions (for reasons I’ll explain later).
For me being on artix btw, I had to install the following through the AUR:
Now, install and set the recommened versions of GHC, Stack and HLS by firing up the tui:
Scaffold a project
Now that we have the tools installed, let’s scaffold a project. We’ll use the
stack new command to get a template project:
To explore further on the
stack new command, look at the
To not download
GHC for every project you create you can make stack use the
GHC version we installed using
GHCup by setting
system-ghc: true in
~/.stack/config.yaml (you may want to fill out some other fields there as
well) or run the following command:
Build and run
Now that we have a project, let’s build and run it:
The Haskell Language Server5 (HLS) is a tool that provides the LSP server for IDE-like features in your editor. I use Neovim as my editor but I’ll show you how to set it up in VSCode as well.
You may use your favourite plugin manager
(lazy.nvim) to set up the config through
nvim-lspocnfig and since we
installed HLS through
GHCup we don’t need to install it through lsp tools like
You can find the full config options on the HLS docs.
You should install
stylish-haskell to get formatting support:
It’s also good to note the haskell-tools plugin which provides some useful features like Hoogle search and more code actions stuff but happy with my lsp config for now.
For VSCode you can use the
extension which provides the LSP client for HLS. However, it was still a pain to
setup for me. I had to add this to my
And only then did the extension would stop installing hls on it’s own and use
the one I installed through
GHCup. Formatting and linting work out of the box
without needing to install anything else.
If you open the
Setup.hs file in your project now you’ll get the follow
After a lot of searching I found the solution to this problem in
this issue on
the HLS repo. While it is still open, the workaround is quite simple and it’s to
hie.yaml file to the root of your project with the following content:
You should have now configured the Haskell Language Server to use the implicit
hie.yaml through stack and disable the LSP for the
That’s it! Now you can finall start writing some Haskell code and put your category theory knowledge to use (which I don’t have). I hope this tutorial was helpful.
You can now flex on those imperative programmers with your Haskell skills 😆.