Skip to content

Instantly share code, notes, and snippets.

@Elvecent Elvecent/
Last active Jan 14, 2020

What would you like to do?
Minimal Haskell Emacs

Minimal Haskell Emacs configuration, from scratch

This little instruction shows how to set up Emacs with some packages to start writing Haskell in a more or less convenient way (including, but not limited to: smart auto completion, type info, autoformatting).

Get emacs

First step: get Emacs for your platform. This should be simple.

Find your init file

That's usually ~/.emacs on unix-like systems. ~ stands for "home folder" and on Windows it's usually AppData\Roaming. Check this out.

Set up MELPA

Melpa is an Emacs Lisp package archive. You should inform Emacs to use it by putting relevant lines in your init file. In short, this:

(require 'package)
(add-to-list 'package-archives (cons "melpa" "") t)

Type C-x C-s (Ctrl+x Ctrl+s) to save. Now you can restart Emacs (close with C-x C-c) or select the code and evaluate region like this: M-x (Alt+x) eval-region.

Further info here.

Install use-package

You can get it from MELPA: in Emacs, type M-x package-refresh-contents RET, then M-x package-install RET. This is a general procedure for installing Emacs packages. At this point, you just need to enter the package name (use-package). However, with use-package, you can simply put package declarations in your init file and Emacs will download them for you.

After use-package is installed, put this in your init file:

  (require 'use-package))

Declare Haskell-specific packages

If you want use-package to automatically install all declared packages, add this:

(require 'use-package-ensure)
(setq use-package-always-ensure t)

Alternatively, specify auto-install for specific packages by putting :ensure t in declarations.


This is the base package for Haskell. It's rather big and even has it's own manual. Here is a simple declaration for it:

(use-package haskell-mode
  :bind (:map haskell-mode-map
              ("C-c C-l" . haskell-process-load-file)))

C-c C-l (Ctrl+c Ctrl+l) is the key binding that actually starts a Haskell process for the mode to communicate with. It is meant to work when haskell-mode is active, which it is by default for .hs files. There are options for pure ghci, stack repl, cabal repl and even cabal new-repl.


Emacs has a package named company that is responsible for completion. It's comes built-in with Emacs distributions. company-ghci is a plugin for that package.

(use-package company-ghci
  (push 'company-ghci company-backends)
  (add-hook 'haskell-mode-hook 'company-mode))

Close Emacs with C-x C-c and open it again (or evaluate the whole file). The packages should load automatically if you declared so. Alternatively, install them with by hand, in the same way you installed use-package.


First of all, get stylish-haskell (or your Haskell formatting tool of choice). You should know where the binary is on your system or just install globally. I prefer handling all this stuff with nix, but you may as well pollute your system as usual by employing stack install or whatever.

Second, enable formatting option in haskell-mode. You can setq the relevant variables directly in your init file, but I like to use Emacs' built-in GUI, like this: M-x customize RET, haskell stylish in search bar. There you can set path to formatter's binary and toggle formatting on save. Don't forget to save your settings with State menu. This will add some ugly lines to your init file.

Try using it

Open a .hs file with some correct Haskell code and do C-c C-l. You should see a new window with repl and all the features like autocompetion should kick in at this point. Send me an angry complaint when something fails.

More good stuff

See haskell-mode manual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.