Many ways to load modules

Posted on March 7, 2018 by Daniel
Tags: Daniel, haskell

I’ve been confused for years by variations of the :load command in GHCi. So much so it often keeps me from using GHCi.

The GHC manual mentions:

That’s a lot of different commands!

import is pretty much like in normal Haskell files

:module is a lot like import, but also allows removing imports, or replacing the entire set of imports. :module is usually right for modules from upstream packages.

:load is usually right for modules in the current project. Technically it both loads and brings in scope. It loads the named module and all transitive dependencies, at which point it’s possible to bring any of them into scope. It brings in scope the named module (exports or top-level, depending). A simple workflow would use :load whenever working on a local module, and never have more than one in scope. Sufficient for type checking. See below for a more complex workflow.

:add is like :load, but saves time by not re-loading already loaded modules.

:reload is the same as rerunning the last :load (or :add?) command.

:module works both for upstream modules and modules that have been loaded (named or transitively). It changes what is in scope, but doesn’t do any of the much slower steps of loading. So for interactive development / testing, it could make sense to load the project, then switch back & forth with :module.


The simple rules I’ve used in the past aren’t actually too bad:

I may try using :add and :module more to get faster feedback when I already have a good idea which modules are broken. I’m looking forward to using the REPL more now that I understand how to get the same terms in scope as in the file I’m working on.