DEV Community

Ken Aguilar
Ken Aguilar

Posted on • Updated on

Haskell - My Setup/Workflow


My setup matches my personality and that is I always go for the simplest solution. I download all these tools using nixpkgs and I enable haskell-mode in doom-emacs. That's it! I start writing Haskell.

This is how my development workspace looks like.

Once I start writing Haskell I have another terminal open that runs ghcid. It has very fast development feedback loop, it's how I know if my types are matching. I use typed-holes heavily so ghcid can tell me what types I need for a section of my code.

Here's a contrived example

add :: Integer -> Integer -> Integer
add x y = x `_whatdo` y

This will be ghcid's response in the repl

<interactive>:3:13: error:
    • Found hole: _what :: Integer -> Integer -> Integer
      Or perhaps ‘_what’ is mis-spelled, or not in scope
    • In the expression: _what
      In the expression: x `_what` y
      In an equation for ‘add’: add x y = x `_what` y
    • Relevant bindings include
        y :: Integer (bound at <interactive>:3:7)
        x :: Integer (bound at <interactive>:3:5)
        add :: Integer -> Integer -> Integer (bound at <interactive>:3:1)
      Valid hole fits include
        add :: Integer -> Integer -> Integer (bound at <interactive>:3:1)
        seq :: forall a b. a -> b -> b
          with seq @Integer @Integer
          (imported from ‘Prelude’
           (and originally defined in ‘ghc-prim-0.5.3:GHC.Prim’))
        (-) :: forall a. Num a => a -> a -> a
          with (-) @Integer
          (imported from ‘Prelude’ (and originally defined in ‘GHC.Num’))
        asTypeOf :: forall a. a -> a -> a
          with asTypeOf @Integer
          (imported from ‘Prelude’ (and originally defined in ‘GHC.Base’))
        const :: forall a b. a -> b -> a
          with const @Integer @Integer
          (imported from ‘Prelude’ (and originally defined in ‘GHC.Base’))
        max :: forall a. Ord a => a -> a -> a
          with max @Integer
          (imported from ‘Prelude’
           (and originally defined in ‘ghc-prim-0.5.3:GHC.Classes’))
        (Some hole fits suppressed; use -fmax-valid-hole-fits=N or -fno-max-valid-hole-fits)

This tells me that I need a function that takes two Integer that also outputs an Integer. This even tells me the "Relevant bindings" and "Valid hole fits" which is amazing. ghcid helps as much as it can. This flow goes a very long way. It starts getting hazy for me when it comes to lens errors, but I'm sure if I use lens more often I'll be able to decipher what ghcid is telling me much quickly. This even works in the type level.

add :: _whatdo
add x y = x + y

ghcid repl will respond with

<interactive>:8:1: error:
    • Couldn't match expected type ‘_whatdo’
                  with actual type ‘Integer -> Integer -> Integer’
      ‘_whatdo’ is a rigid type variable bound by
        the type signature for:
          add :: forall _whatdo. _whatdo
        at <interactive>:7:1-14
    • The equation(s) for ‘add’ have two arguments,
      but its type ‘_whatdo’ has none
    • Relevant bindings include
        add :: _whatdo (bound at <interactive>:8:1)

ghcid is the reason I don't use any IDE or any fancy editor plugins. I only have syntax highlighting and some formatting in my emacs.

When it comes to actually running my code I usually use cabal. After ghcid tells me my code is clear I run

cabal new-build
cabal new-run

Sometimes I use stack because of yesod. That's mostly for work.

I'm aware of the holy war between stack, cabal, and nix, I hope this blog doesn't get involved in that war. I use all of them. They all have a spot in my workflow.

Discussion (3)

lautarolobo profile image
Lautaro Lobo

What are some projects which you worked on with Haskell? I'll be glad to know. Because, we see Haskell at College, it's in our Computer Science curriculum, but we don't really see practical uses of it...

piq9117 profile image
Ken Aguilar Author • Edited on

Hey! thanks for bringing that up. It's unfortunate to hear that is the reputation of Haskell in your university. I don't have a lot of public repos, I got this one It wraps the plaid api so it's easy for me to consume in Haskell.

There are also other projects out there like haxl(, a facebook library. They use that to control spam. Recently, github also released semantic ( It powers this feature

Haskell has a range of practical use, from scripting to obscure CS research. If you want to interact with a lot more haskellers you should join this slack channel

lautarolobo profile image
Lautaro Lobo

Hey, thanks!