This is a distro agnostic simple guide on how to setup haskell on modern linux using GHCup.

Requirements

Make sure you're equipped with all the neccesary packages to run GHCup properly. I'm not gonna list all of them here (if you're a dev already, chances are you're).

So just go here and check -> https://www.haskell.org/ghcup/install/#system-requirements

For an example,

if you're on Arch Linux, you just need the linux-devel and curl packages and rest will be automatically downloaded installed by the GHCup installer.

Setting up

1. Paste the following command and run:

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

This script will download and install the following binaries:

  • ghcup - The Haskell toolchain installer
  • ghc - The Glasgow Haskell Compiler
  • cabal - The Cabal build tool for managing Haskell software
  • stack - A cross-platform program for developing Haskell projects (similar to cabal)
  • hls - (optional) A language server for developers to integrate with their editor/IDE

Note that HLS (Haskell Language Server) is optional here. Make sure you install that when the installer prompts you if you want to use code actions, suggestions, goto definitions, and etc in Neovim (There are other LSPs but I highly recommend this for a beginner).

2. When installer prompts asking to write environment variables to your shell configuation, let it do that.

It will add something simillar to following your shell configuration.

[ -f "/home//.ghcup/env" ] && . "/home//.ghcup/env" # ghcup-env

3. After the installer finishes up, reload your shell configuation, close and reopen your terminal.

source .zshrc # for zsh
source .bashrc # for bash
source ~/.config/fish/config.fish # for Fish

# If you're using a different shell refer it's manual

4. Make sure everyting is correctly installed:

$ ghc --version

Should print The Glorious Glasgow Haskell Compilation System, version 9.6.7

$ which haskell-language-server-wrapper

Should print /home//.ghcup/bin/haskell-language-server-wrapper

5. You can manage what has installed or install new tools using the below command:

ghcup tui

Make sure ticks are like in the below image in the ghcup tui:

ghcp tui
Double tick means installed and set as default. If hsl is not set, set it with s.

Configuring neovim

1. If you're new to Neovim ( which I highly doubt) start with something like kickstarter neovim config by TJ.

Following steps assume that you have a lazy.nvim and nvim-lspconfig plugins installed and configured to the way you like.

2. Setup treesitter for syntax highlighting:

{
  "nvim-treesitter/nvim-treesitter",
  lazy = false, 
  build = ":TSUpdate",
  config = function()
    -- treesitter configs
    local config = require("nvim-treesitter.configs")
    config.setup({
      auto_install = true, -- Auto install treesitter parsers when a new file type detects
      highlight = {
        enable = true,
      },
      indent = { enable = true },
    })
  end,
}

3. There are multiple ways to start lsp servers using nvim.lspconfig. I will show the one I use here (which extentable later for other langs easily):

{
  "neovim/nvim-lspconfig",
  opts = {
    servers = {
      hls = {}, -- Pass Haskell Language Server to the opts table
      -- your other language servers can be listed here
    },
  },
  config = function(_, opts)
    -- config function using opts.servers

    -- Loop over the servers in opts.servers and enable each
    for server, config in pairs(opts.servers) do
        lspconfig[server].setup(config)
    end
  end,
}

4. Check if the Tree-sitter parsers and LSPs are attaching to the buffer.

  • Open up a new haskell file:
nvim hello.hs

Give some time for nvim treesitter to download the haskell parser

  • Check Treesitter:

Type the below command in your neovim cmdline in command mode and it will show avaiable active parsers.

:TsModulInfo
  • Type following command in the neovim command mode to verify if the LSP is attached to your buffer.
:LspInfo

Another good way to verify is to type some Haskell syntax. If your editor shows like below, you're good to go:

haskell-in-action-in-neovim

That's it!

Enjoy your functional programming :)