Configuring Vim for Haskell

I've started to get more into Haskell lately and one of the things I really enjoy is the strong tooling built around the language. This tooling mostly relies on the fact that the compiler is very powerful and can do lots of cool things.

I've played around with a few plugins that make writing Haskell in Vim more pleasant.


I use this plugin together with Syntastic to get type errors directly within Vim every time I save a file. It quickly becomes annoying to have to manually compile your files every time you wanna see if you've made some silly mistake Doing it manually also doesn't allow you to look at your code and errors at the same time. It basically tightens the feedback loop, to use TDD terminology.
hdevtools is great because it uses a background server that makes the type checking really really fast. There is only a very small noticeable delay, much smaller than with ghcmod.

I have made the following configurations to Syntastic:

let g:syntastic_mode_map = { "mode": "passive",
                           \ "active_filetypes": [],
                           \ "passive_filetypes": [] }

let g:syntastic_haskell_checkers = ["hdevtools"]
let g:syntastic_haskell_hdevtools_args = "-g -Wall -g -fno-warn-unused-do-bind"
let g:syntastic_mode_map = {
    \ "mode": "passive",
    \ "active_filetypes": ["haskell", "c", "cpp"],
    \ "passive_filetypes": [] }

This will turn on all warnings for GHC except for unused binds in a do expression. It also enables Syntastic only for C, C++ (Vim thinks ".h" files are C++), and of course Haskell.

I also use it sometimes for looking at the types of expressions, for which I've made the following leader mappings:

nnoremap <leader>ht :HdevtoolsType<CR>
nnoremap <leader>hc :HdevtoolsClear<CR>
nnoremap <leader>hi :HdevtoolsInfo<CR>

I have been experiencing some issues where it reported errors with my code, but it compiled just fine. In that case running rm .hdevtools.sock often fixed the issues. One time I had to update the plugin for the false negative to go way.


This plugin does a whole lot of stuff, but I basically only use it for syntax highlighting. I really only have one complaint: If the name of a function includes a single quote (') then the type signature wont be highlighted properly. I might make an issue at some point, or look at the code myself.


I haven't yet done that much testing in Haskell so at the moment I've configured vim-spectacular to simply open ghci with the current file. This is useful for doing manual testing which I've found to be sufficient so far.

PS: Should you be curious, my dotfiles are on GitHub.

RSS Feed

You might have noticed that I used to have a broken link on the about page to the RSS feed for this blog. I'm happy to tell you that that has been fixed. That means you can now subscribe to the RSS feed get notified when new posts are published.

You can find the feed here. You can also just paste into your RSS feed reader and it should discover it. I recommend reeder for both Mac and iOS.

Laziness in Haskell

Recently I've been playing around with Haskell. For those who are not familiar Haskell is a pure, functional and lazy (by default) programming language.

Most programmers nowadays are familiar with functional languages. Pretty much all modern languages have functions like map, reduce, filter, etc. built-in, and those are essentially higher order functions coming from the world of functional programming. Lots of people are also talking about the benefits of immutability, which is also something that comes from the functional world. But I doubt most people are familiar with lazy languages. Thats probably because the only widely adopted lazy languages is Haskell, and not that many people are familiar with Haskell.

However, consider the following piece of Ruby code:

require "benchmark/ips"

a = (1..2000000).to_a

Benchmark.ips do |x|"several maps") do
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .reduce(0, :+)
  end"one map") do
      .map { |x| x + 1 + 1 + 1 + 1 }
      .reduce(0, :+)

Which of these two implementations do you think is faster? Common sense says it should be the last one called "one map". There we are only looping through the array once: One time doing the map and adding four to each element, and a second time to compute the sum. In contrast to the first one where we map across the list four times adding one each time.

If we run this code, Benchmark.ips gives us something like this:

Calculating -------------------------------------
        several maps     1.000  i/100ms
             one map     1.000  i/100ms
        several maps      1.907  (± 0.0%) i/s -     10.000
             one map      4.314  (± 0.0%) i/s -     22.000

             one map:        4.3 i/s
        several maps:        1.9 i/s - 2.26x slower

It clearly shows that in fact doing several maps is way slower than just doing one. Everything is as we expected.

If we try to do something equivalent in Haskell we get a different result. Here is a piece of Haskell code thats equivalent to the first example where we mapped multiple times:

module Main where

main :: IO ()
main = do
    let x = [1 .. 2000000]
    print $ foldr (+) 0 $ map (+ 1)
                        $ map (+ 1)
                        $ map (+ 1)
                        $ map (+ 1) x

And here is the other version where we map only once:

module Main where

main :: IO ()
main = do
    let x = [1 .. 2000000]
    print $ foldr (+) 0 $ map (\x -> x + 1 + 1 + 1 + 1) x

Lets compile these two programs and look at the time output:

$ ghc -O2 Once

$ ghc -O2 Several

$ time ./once
./once  0.23s user 0.03s system 99% cpu 0.270 total

$ time ./several
./several  0.23s user 0.03s system 99% cpu 0.267 total

To our surprise we see that both versions take the same amount of time. This is because Haskell is a lazy. The execution of the program goes something like this:

  • It sets x equal to the list of integers from 1 to 2000000. However it doesn't actually build the list yet, because its lazy.
  • It prints the sum of the list after mapping, which requires that foldr does its job.
  • Since foldr loops through the values in the list one at a time, it requests the values to be computed one by one, not all at once.
  • The first input value to foldr is the last value in the list after mapping. This value is computed by figuring out what the last element in the list (without evaluating the whole list) and applying the maps to that value. Note that we are only mapping one value, because foldr haven't requested the whole list, just the last element.
  • foldr now adds the initial value and the mapped one, requests the next value and so on until the list is empty.

By doing this its clear that doing four maps or one takes equal amounts of time. Because they're not evaluated before foldr requests the result.

I think this way of programming, when you're working with lists especially, is really great. It allows you to separate the different parts of your algorithm into smaller functions without sacrificing performance because you're iterating the same data structure more than once. Its something I really miss when I'm in Ruby.

Write everything in Vim

Chris Toomey mentioned in an episode of Upcase's The Weekly Iteration that he writes pretty everything in Vim. It doesn't take much typing before a piece of text in a text area gets copied into Vim, typed, edited, and pasted back. Typing it in Vim is just that much faster.

I thought this was interesting and I thought that it should be possible to automate this with Keyboard Maestro. What I want this a macro that does the following:

  • Copy everything in the current text field.
  • Open a new empty window in MacVim.
  • Paste the text I just copied.
  • Let my type it out.
  • Copy the text out of MacVim and back into where I was.

Turned out that making a script like this is totally possible. All I have to do is press cmd+ctrl+v and all that magic happens. Once I've typed the text, I hit cmd+ctrl+v again and I'm right back where I was.
I've been using it for a couple of hours now, and its great!

If you wanna play around the macro you can download it here.


I've done a small amount of pair programming in the past and I would like to build a habit of routinely pairing with people.

If you're interested here are some details:

  • I live in Copenhagen, timezone is UTC +1.
  • I have experience with Ruby+Rails, iOS, JavaScript, Haskell, but I'm open to pairing on everything
  • I suggest we use Tmux and Vim, unless you have other good ideas

I don't have any specific projects I would like to pair on, so if you don't have any ideas either, we'll have to come up with something. Maybe some upcase exercises.

I would very much like to get better at Haskell so if you have experience please let me know.

If you're interested just send me an email.

Programming language roadmap

I recently listened to an episode of the Ruby Rogues podcast in which Avdi Grimm mentioned his personal programming language roadmap. This is a list of languages that he would like get more familiar with in the future because he believes they'll make him a better programming. I thought this was a great idea so I've compiled my own list. The list is somewhat sorted after priority:

  • Haskell - I have already written a fair amount of Haskell, but it has mostly been on compiler related assignments for school. I would like to get more experience building more common things in Haskell.
  • Rust - I've always been afraid of C, and the course on operating systems I finished about a month ago just made my fear bigger. I would however like to know a language suited for doing systems programming, and Rust seems to be the way to go.
  • Erlang/Elixir - Because currency gets more important everyday and I like the idea of a functional but dynamic language
  • Smalltalk - I feel like I already kinda know Smalltalk after so much Ruby programming, but I would still like to get familiar with it. If not then just to learn more of where Ruby came from.
  • Clojure - Because I wanna get familiar with a real production ready lisp. I would also like to get familiar with a different model of concurrency than Erlang.

Some Git tips

I grew up with Git. I've never used another version control system, so to me the way Git works is quite natural to me and my brain is used to the distributed model with SHAs everywhere.

This post goes through a few of things I've setup to make working with Git more pleasant and faster.

Viewing the log

I feel like getting a good Git log is the most important thing to do. It will help you understand so much about how Git works and what the history of you repository looks like. Luckily there is a gem called git-smart that makes it dead simple to get a nice looking log. Here is what the log for the Rails repository looks like, if you use git-smart:

Rails git log

I've set two aliases for viewing the log that I use constantly. They are gl and gll. gl shows a log of the 10 most recent commits, as those often are the most relevant ones, and gll shows the whole thing.


I have a ton of Git aliases. You can find them all here. Here is a list of my most frequently used ones:

  • g: If run by itself it'll show a short status, if run with arguments then it works like git.
  • gaa: Add all unstaged files.
  • gap: Add files in patch mode.
  • gc: Commit verbosely (show diff) and write message in $EDITOR (Vim in my case).
  • s: Show short status.
  • d: Show diff.
  • gdc: Show diff of staged files.
  • gl and gll: Covered in previous section.
  • g lol: Show a complete log with all branches, stashes, etc. Useful for seeing where all the different branches are in relation to each other. You can find the config for this here

Rebasing vs merging

I've heard from quite a few people that they are afraid of rebasing and only ever merge stuff because they are afraid of loosing stuff. This is probably because they don't fully understand the fact that you can't ever loose anything thats been committed in Git. Not by rebasing, or even doing hard resets.

If you're in the middle of a rebase and you realize that its not going well you can run git rebase --abort to undo the whole thing. And if you've done a rebase and you wanna undo it, just run git reflog, find the SHA of the commit before you made the rebase, and reset --hard to that point. This last tip also works great to undoing merges that didn't go well.


There is also no need to be scared of reset. Remember as soon as something has been committed, you can't loose it. If you happen to reset to a point you didn't mean to reflog got your back. Again just find the SHA of the commit you were on and reset --hard back to that. All reset --hard does is move you to whatever revision you give it.

Keeping the current branch and SHA in prompt

My prompt

One tip I got from this screencast was to keep the SHA of you current commit in your prompt. It might seem like overkill, but its actually really useful. I mostly use it for finding the place I wanna reset back to after having done something stupid. This can also be done with the reflog, but just scrolling up through your commands might be more direct sometimes.

You can find the script I use here and my prompt configuration is here.

If you wanna learn more about Git, Pluralsight has a great screencast about advanced git.


← Archive