Sunday, July 31, 2016

Setting up Emacs for Haskell

Haskell is a bit of a quirky language. It has been around for a very long time, yet hasn't nearly received the professional love that languages like Java, C#, or even F# have gotten. Professional IDE's for the language doesn't exist; good IDE plugins for the languages barely do. So, it has become standard within Haskell community that either Emacs or Vim be used. In this article we'll be examining how to start working with Emacs and Haskell effectively.

First Things First
Prerequisites 
We have to get Emacs and Haskell installed, if they're not already. If you already have emacs and ghc installed, then you can safely skip this step. Otherwise, you need to install the following packages:

emacs (Version 24 or greater)
ghc (Version 7.5 or greater)

Ubuntu
sudo apt-get install ghc emacs
Fedora
sudo dnf install ghc emacs
Arch
sudo pacman -S ghc emacs
Melpa
The next steps are much easier to perform if you already have Emacs set to look at the MELPA repositories. If you'd like instructions on how to set up MELPA, I've written a guide about it Here.

Emacs Packages

The Emacs package which controls Haskell can be found in the "haskell-mode" package. The two other helpful packages that are also in the MELPA repositories are haskell-emacs, which lets you make Emacs extensions in Haskell, and haskell-snippets, which will present a certain type of code completion into Emacs for haskell by the use of yasnippet.

To install the necessary packages, do:

M-x package-install [ret] haskell-mode [ret]
M-x package-install [ret] yasnippet
M-x package-install [ret] haskell-snippets [ret]
haskell-snippets and yasnippet are completely optional, but they will make your experience far better.

Configuration
 A bit of a frustrating trend with haskell-mode is that it's making more and more features opt-in, in order to reduce the memory overhead of using haskell mode. What this means for the average user is inconvenience in configuring haskell-mode.

In your ~/.emacs file (or wherever you prefer to extend Emacs from), put in the following lines:

(add-hook 'haskell-mode-hook 'haskell-indentation-mode)
(add-hook 'haskell-mode'hook 'interactive-haskell-mode)
(add-hook 'haskell-mode-hook 'yas-minor-mode)
Or, if you plan to use all of these features:
(add-hook 'haskell-mode-hook (lambda () (interactive) (haskell-indentation-mode) (interactive-haskell-mode) (yas-minor-mode)))
This makes it so that when you enter haskell-mode (which you do when you open any .hs file), the haskell indentation mode, interactive haskell mode, and the yas minor mode are all enabled.

haskell-mode is what provides syntax highlighting for haskell, amongst a few other features.
haskell-indentation-mode is what allows you to automatically indent haskell source with text
interactive-haskell-mode is what lets you run Haskell code right in Emacs to check for errors, make tests, etc.
yas-minor-mode lets you insert snippets of Haskell code into the file you're in, which makes working with Haskell far easier, due to the immense amount of syntax sugar that Haskell makes use of.

Using Emacs for Haskell
Let's make sure that we have everything working. In Emacs, open up a file called "test.hs" and add the following lines:

myFunction :: (a -> b) -> a -> b
myFunction f a = f a
myFunction2 :: Int -> Int
myFunction2 a = myFunction (+ 2) a
Now, do C-c C-l (hitting c and l while holding control). If everything is installed correctly, it should show you a lambda and a greater-than symbol. This is a ghci prompt, which will evaluate your current file and let you interact with the functions and data types you've defined in this file or any that are imported into it.

Just to see what would happen when there's an error, change the first line to this:
myFunction :: (a -> b) -> a -> c 
And try to run C-c C-l again. Notice that it leaves a white exclamation point to the right of the problem in the source code, and underlines exactly where the error is in red.
  as well as showing you the error in the bottom part of the window
This is how your Emacs workflow will go.

Further Reading
There is plenty more to do with Emacs and Haskell, but this will get you started. You can activate true code completion, get linting messages, etc. through the use of an extra extension called ghc-mod. However, ghc-mod is currently broken in cabal... Whenever the version in the cabal repositories is fixed, I will add information about ghc-mod to the guide.

If your distribution has ghc-mod, it's would betroth you to read about installing it in Emacs here.

No comments:

Post a Comment