Developing Haskell using Atom
I’m picking up pace on Haskell development, with useless early versions of two packages now on github:
- hakyll-site - a bare-bones static site generator using Hakyll
- hask-mrt - A parser for multi-router toolkit (MRT) export files
This article outlines the tool chain I’m now using to do this development.
Building code
You can start to get a sense of how I do this by looking at those two repositories, where right off the bat you’ll see that I’m using stack for building, and where possible using Travis CI to test my builds.
Using stack frees me from the cabal sandbox concerns of whether the environment is applied appropriately, particularly for tools invoked other than directly from a shell prompt where I need to take care to ensure the path is right. It also gives me the stable set of packages, but this isn’t the full Hackage, and already I’ve noticed a few packages missing.
The blog itself is run using a trio of Docker containers: an nginx server to
spit out the content, a builder image which pulls the latest git version,
rebuilds the site executable as necessary, rebuilds the site itself, and copies
it into place, on the third image, a data container. A git post-receive
hook
triggers the site rebuild container, so blog updates are always just one push
away.
Writing code
The major change for me, though, is that I’m using Atom as my editor. I’ve been a vim user for a few decades now, and while developing Haskell code in vim works well enough that I’m comfortable doing it via ssh, a number of Atom packages make development just that little bit nicer.
First, I often use some Markdown somewhere, and as hakyll-site
might suggest,
I also often wind up generating web sites. Atom has excellent support for HTML,
CSS, less, JavaScript, and with the markdown-preview-plus package, pandoc
Markdown support including LaTeX math.
Second, I rely heavily on hlint to make me a better Haskell developer, and too much time developing Java has made me fond of autocompletion. To satisfy these needs, and the additional bonus of showing expression types on mouse hover (mitigating my most common use of the REPL: type composition), ide-haskell and its supporting packages really shines.
Making it work
To make ide-haskell work well, you need to install ghc-mod, and to work with stack that means version 5.4.0.0. I installed using the Mac homebrew version of Cabal, and given stack tends to prefer my system GHC over installing its own copy, this leaves me with an appropriately linked set of tools. I also installed stylish-haskell to clean up my indenting and import lists via the IDE.
$ stack install ghc-mod
… time passes …
$ stack install stylish-haskell
… much more time passes …
The full set of packages I’m currently making use of are:
- autocomplete-haskell
- Auto-completion tied to ghc-mod, so it actually knows my code
- haskell-ghc-mod
- The autocompletion and ide backend provider. Configuration is mostly about managing paths correctly, now that both this package and ghc-mod fully support stack projects.
- ide-haskell
- Errors, warnings, lints, hover-over type information, and code clean-up. The linting, in particular, is a real winner.
- language-haskell
- Syntax highlighting for Haskell and cabal files. A requirement for most of the other packages, too.
- markdown-preview-plus
- The thing that’s showing me my typos in real-time as I make them working on this article. Regrettably, there is no linter available for writing style.
- hard-wrap
- On demand word-wrap for text or Markdown files. I’m not big on soft wrap, and hard-wrap does the job perfectly for me.
Configuration overall is pretty straightforward. Atom ties into git flawlessly,
to the point that issuing a git mv
from a shell results in Atom’s editor pane
reflecting the new file name, without losing my cursor position in any open
files.
Being productive
My vim setup is reasonably complex, and my familiarity with the modal editing gives me plenty of technical efficiency for making changes. But when I write code, I don’t really need technical efficiency so much as I need cognitive efficiency - linting, type checking, quick access to docs, and of course REPL behaviours tend to weigh much more than how rapidly I can indent 20 lines. Atom gives me that cognitive assistance for a wide range of tasks, in one place.
My current project at work involves prototyping a user interface for a new system, and this means some Haskell to generate a static site, some Markdown for the straight up descriptive text, some HTML for the interface prototypes, and a lot of SVG for the shiny new bits. Atom’s made all of that pretty much seamless, with the one minor down side that so far I don’t have a great setup for previewing SVG as I edit it - which is potentially a new project to embark on.
Oh, never mind. Time to install a new package.