Quick tips for fast iteration in Haskell | The Haskell Programming Language's blog
Quick tips for fast iteration in Haskell
Tom Ellis,<br>Laurent P. René de Cotret July 28, 2026 [Ecosystem] #Practices #Tooling
Introduction
The Haskell community has recently been discussing how to achieve fast<br>iteration times when type checking and compiling Haskell code. Fast<br>feedback has always been important in software development, and we're<br>seeing increased interest in the topic in recent months due to the<br>rise in prominence of agentic coding.
This article describes two techniques for fast iteration: using ghci<br>to get fast feedback on the result of type checking an compilation,<br>and speeding up builds with a careful choice of flags to ghc and<br>cabal. These techniques can be run on any existing codebase. They<br>don't require you to restructure your code in any way, so you can get<br>an instant improvement to your iteration times. Let's dive in!
ghci-based
GHCi is GHC's interactive<br>interpreter<br>(executable name ghci) which comes bundled with every installation<br>of GHC. It is a REPL ("read-eval-print<br>loop"),<br>which means you can type expressions into it and it will run them,<br>printing the result. ghci is a good starting point for fast<br>feedback because it doesn't have to fully compile code, rather it<br>generates executable bytecode and skips machine code generation,<br>making it inherently faster than a normal build.
There are a variety of ways to use ghci, from using barebones ghci<br>itself directly to featureful wrappers.
ghci itself
You can invoke ghci with a collection of source paths and it will<br>compile and load those modules, for example:
ghci src/Path/Module1.hs src/Path/Module2.hs<br>Or, perhaps more useful, use a ghci invocation wrapper that comes<br>with your build tool, cabal or stack:
stack ghci<br>cabal repl<br>For a simple ghci workflow, make some changes to the files in your<br>project, then navigate to your ghci window and type :reload (or<br>:r for short). ghci will type check and compiles your changes,<br>printing any errors or warnings from GHC. Simple!
You might feel that continually typing :r ought to be automated<br>away. If so then check out the next section on ghcid.
ghcid
ghcid is a wrapper around ghci that automates issuing :r when<br>any file in your project changes, so its workflow is even easier than<br>that of ghci: make some changes to the files in your project and<br>then merely look at your ghcid window; ghcid will have detected<br>your changes and the result of type check and compilation will appear<br>automatically.
Automatically running tests
ghcid also allows you to get more quick feedback than just the<br>result of type checking and compilation: you can run tests (or indeed<br>any code) when your source files change. There are two ways to do<br>this:
Embed comments with expressions to be evaluated. For example add<br>this comment to a source file to evaluate expr after loading:
-- $> expr<br>(Evaluating embedded comment expressions requires using the<br>--allow-eval flag.)
Pass an expression to the command line option --test, to run<br>after the code is loaded successfully, for example:
ghcid --test myTestFun<br>(By default the test expression will only run if the code is<br>warning-free. To run the test expression even if there are<br>warnings, also pass --warnings.)
For more information on these features, see the<br>Evaluation section<br>of the ghcid README.
Installation
ghcid is a normal executable package on Hackage, so you can install<br>it with, for example, cabal install ghcid.
ghcid-check
One limitation of ghcid's default behaviour is that it is not<br>programatic. When you change source files, ghcid's updates appear<br>in the terminal in which it is already running. That's no good if you<br>want to give fast feedback to a coding agent; ideally the coding agent<br>would run a command line executable to obtain the feedback.
That's fine, because ghcid supports that too, with its --reload and<br>--outputfile options. But setting that up is a little fiddly, so<br>here's a simple ghcid wrapper bash script called ghcid-check:
https://github.com/tomjaguarpaw/ghcid-check/
ghcid-check is very basic and you might want to customize it to meet<br>your own particular needs.
Beyond ghcid, there are another couple of projects based on a<br>similar idea that bring new features: ghciwatch and Tricorder.
ghciwatch
ghciwatch<br>is an updated take on ghcid, from the Haskell developers at<br>Mercury. Compared<br>to ghcid it has more sophisticated checking for new, removed and new<br>modules, which sometimes trip up ghcid, as well as other new<br>features.
Tricorder
Tricorder is from<br>Tweag and provides even more live status and diagnostic updates than<br>ghcid or ghciwatch, including access to documentation and<br>machine-readable output, and is designed from the ground up to be<br>usable programatically by coding agents as well as interactively by<br>humans.
Check out the announcement<br>post<br>on the Haskell Discourse, which includes a short video of Tricorder<br>functionality. tricorder is a normal executable...