We’ll start with a basic overview to see what working with GHCi is like: how to run it, how to use commands, and how to read its output.
Assuming you already have a working installation of GHC on your machine, you should be able to open a GHCi session by typing
ghci on the command line from any directory that can access GHC.Both of the major build tools,
stack, have their own commands to open project-aware REPLs, but using those will not be our focus here. Further documentation is available here for
cabal users and here for
stack users. One benefit of using these is that opening a GHCi session from within a project directory using, e.g.,
stack repl, may load your
Main module automatically and also make the GHCi session aware of the project’s dependencies.
Haskell expressions can then be typed directly at the prompt and immediately evaluated.
GHCi will interpret the line as a complete expression. If you wish to enter multi-line expressions, you can do so with some special syntax.
Invoking GHCi with options
You can open GHCi with a file loaded from the command line by passing the filename as an argument. For example, this command loads the file
fractal.hs into a new GHCi session:
If that module has dependencies other than the
base library, though, they won’t be loaded automatically. We’ll cover bringing those into scope in a separate section, below.
You can also open GHCi with a language extension, for example, already turned on. For example,
But if you pass it the
-XOverloadedStrings flag, then that language extension will be enabled for that session.
A great number of other GHC flags can be passed as arguments to
ghci in this fashion. For the most part, we will cover those as they come up in other contexts, rather than attempting to list them all here.
Your GHCi configuration, if you have one, will be loaded by default when you invoke
ghci. You can disable that with a flag:
There are a few ways to bring modules and packages into scope in GHCi. One is using
cabal to open a project-aware REPL, which usually works well to bring the appropriate dependencies into scope. However, there are a few other options.
You can import modules directly in GHCi using
import, just as you do at the top of a file if your GHCi is already aware of the package the module comes from.
All modules in
base are fair game for importing, as are modules in a project-aware GHCi session or a GHCi session that has been invoked with the
-package flag, thus loading the package into the session.
All the same import syntax is available for this, such as
base package is always loaded by default into a GHCi session (as is the
Prelude module, unless you have disabled that), but that’s not, of course, the case for many packages. However, your GHC installation came with a few packages that are available but not automatically loaded into new GHCi sessions. You can find out what you have available by running
on the command line. You should see a list of all the packages that are installed and available. Modules from any of those listed packages can be directly imported, just as if they were in
base. So, assuming your list includes
containers, you can type
import Data.Map or the like directly into your GHCi session, regardless of whether it’s one of your project’s dependencies – or if you even have a project going.
If you are using a
cabal REPL, then there may be many more packages in their local package lists that are available to new GHCi sessions. If you have previously opened a GHCi session with something like
stack will have installed
QuickCheck and, if in the future you open a
stack repl session but forget to pass the
--package flag and then suddenly you realize you want to make
QuickCheck available in this GHCi session, you can
:set -package within GHCi to bring it into scope:
It’s really handy not to have to restart a GHCi session just to load a package you use frequently!
First let’s start with a couple of basics: you can use the up-arrow, down-arrow, and tab-complete in GHCi, so if you are already comfortable with these from your bash shell or what have you, you’ll enjoy this.
Furthermore, if you are in a GHCi session, shell commands can be made available using the
:! GHCi command. For example, let’s say we’ve forgotten what directory we’re in and what files are in this directory, but we don’t want to quit GHCi to find out. No problem!
:cd command doesn’t need the
To quit a GHCi session, use
GHCi commandsMuch of this course will be about GHCi commands. List of commands gives an overview of all of them, and several other lessons elaborate on specific commands of particular importance. all start with a colon (except
import). They may all be abbreviated to just their first letter; however, if there is more than one command that starts with the same letter, such as
:module, it will default to reading that as whichever is more commonly used. When in doubt, type it out.
You can type
:? for a complete listing of the GHCi commands.
GHCi assigns the name
it to the last-evaluated expression. If you aren’t using
:set +tWe will see
:set +t and other uses of
:set later in the page on the GHCi :set command. to automatically display types for expressions entered into or evaluated in GHCi, then you might not notice
it until you see an error message that mentions
it such as this one:
λ> max 5 _ <interactive>:76:7: error: • Found hole: _ :: a Where: ‘a’ is a rigid type variable bound by the inferred type of it :: (Ord a, Num a) => a ----------------------------------- ^^ at <interactive>:76:1-7 • In the second argument of ‘max’, namely ‘_’ In the expression: max 5 _ In an equation for ‘it’: it = max 5 _ ------------------------- ^^
It isn’t always important or useful to recognize that GHCi has named the expression, but there’s at least one interesting thing about
it that you may find useful. Here’s a clue:
GHCi is always implicitly running the
it. But it’s not only GHCi that can pass
it as an argument to functions – you can, too!