I started a Haskell rewrite of a project, and after not having used Haskell for a long time, found the process of setting up my Vim environment to be a pain.

There’s nothing exciting here, but by the end of this quick guide you should have:

  • Haskell + Stack installed
  • Autocompletion, go to definition, type lookups, and more via HIE and CoC
  • GHCi via Intero (it does more, but overlaps with HIE a bit)
  • Local hoogle

For vim packages, I’m going to assume you’re using vim-plug, replace Plug with your plugin manager of choice if you’re using something else.

Installing stack

This one’s easy:

curl -sSL https://get.haskellstack.org/ | sh

Create a projet via stack, this will also install GHC

stack new myproject

CoC

CoC is, in my opinion, far and away the best language server integration for vim currently. It has plugins for bunch of other stuff too, like formatting, linting, and snippets.

Installing CoC is as easy as vim plugins get (refer to the docs if you’re not using vim-plug):

Plug 'neoclide/coc.nvim', {'do': { -> coc#util#install()}}

Open a new vim instance, and verify CoC is installed by running :checkhealth.

HIE (Haskell IDE Engine)

HIE

The easiest way to install HIE is through the Nix package manager:

bash <(curl https://nixos.org/nix/install)
nix-env -iA cachix -f https://cachix.org/api/v1/install
cachix use all-hies
nix-env -iA selection --arg selector 'p: { inherit (p) ghc865; }' -f https://github.com/infinisil/all-hies/tarball/master

To get nix-env and cachix to work in new shells, I had to add the following to my ~/.zshrc (~/.bashrc if you use bash):

source $HOME/.nix-profile/etc/profile.d/nix.sh
export PATH="$HOME/.nix_profile/bin:$PATH"

You can test that HIE is installed by running hie.

Now, you’ll need to connect CoC to HIE, as it doesn’t look for it by default. Run :CocConfig in a vim instance, and add the following to your config:

  "languageserver": {
    "haskell": {
      "command": "hie-wrapper",
      "rootPatterns": [
        ".stack.yaml",
        "cabal.config",
        "package.yaml"
      ],
      "filetypes": [
        "hs",
        "lhs",
        "haskell"
      ],
      "initializationOptions": {
        "languageServerHaskell": {
        }
      }
    }
  }

Now, try editing a haskell file in your project and see if you get autocompletion. An easy test is to write import Data. and see what comes up. Note that sometimes HIE takes some time to startup for a new instance, give it ~20 seconds if it doesn’t work right away.

Intero

Intero gives you a constantly-reloading GHCi prompt for your project. It’s very useful for playing around with libraries and testing your functions.

First, add the following to your vim config file

Plug 'parsonsmatt/intero-neovim'

I had some trouble with getting Intero to install, on MacOS Mojave. It’s supposed to install itself, but I ended up having to do:

stack build intero --copy-compiler-tool

These are the mappings I like for Intero:

" Intero
augroup interoMaps
  au!
  " Background process and window management
  au FileType haskell nnoremap <silent> <leader>is :InteroStart<CR>
  au FileType haskell nnoremap <silent> <leader>ik :InteroKill<CR>

  " Open intero/GHCi split horizontally
  au FileType haskell nnoremap <silent> <leader>ioh :InteroOpen<CR>
  " Open intero/GHCi split vertically
  au FileType haskell nnoremap <silent> <leader>iov :InteroOpen<CR><C-W>H
  " Automatically reload on save
  au BufWritePost *.hs InteroReload
augroup END

That’s it

That should be all you need to get going with Haskell. If you experience any issues, feel free to reach out to me.