Using the REPL

Haskell has a nice REPL known as GHCi, where GHC refers to the main Haskell compiler and the ‘i’ is for interactive. GHCi and the continual typechecking tool called ghcid are useful for fast feedback loops while you code, but GHCi has a lot of other features besides. This is a very basic introduction to some of those.

You open a new GHCi session with the ghci command. You can load the file you’re working on as you open a REPL session by passing the filename as an argument to the ghci command.

You can also load a file after GHCi is open by using the :load command, or :l for short, with a filename as an argument.

As you make changes, use :reload or :r. This doesn’t take a filename argument. It reloads whatever was last loaded, whether that was one file or a whole project’s worth of files.

To check what the last file(s) you :loaded is, use :show modules to find out.

Any imports that a file lists are also available once the file is loaded into GHCi. However, you can also import modules directly into the REPL, for exploration and experimentation, if the package is available. Use import along with the module’s name. Use :show imports to see what has been imported.

Modules of base such as Data.Char are always available.

Many functions and types available in base, such as isSpace from Data.Char, are not included in Prelude.

Libraries that GHC has a dependency on, such as the time library, are also available.

Packages from your project’s dependencies or previous installations using cabal install or stack install may also be available. You can check what packages are available to your local GHC before you open a GHCi session. Any of the modules from any of the packages in that list can be imported directly in GHCi.

You can declare values at the REPL prompt as well as evaluate functions, on those values or others. The Prelude module of the standard library (called base) is always in scope by default in GHCi sessions, so all those functions and types are available for use.

Functions can also be declared directly at the prompt. Here f is the name given to the combination of map and length used above.

You can also declare custom types in the REPL. Notice the similarity in style of the declarations.

There is special syntax for multiline expressions in the REPL. This example uses the default multiline syntax while preserving the layout of the code as it would appear in a text file.

Some find this style of multiline syntax more convenient. It must be enabled using the :set +m command. This command automatically turns on multiline syntax when it recognizes that the line ends in a block-opening keyword, such as of or do.

Note that this example uses curly braces and semicolons instead of indentation, although indentation would have worked just as in the previous example.

Multiline syntax is most useful when copying and pasting code into the REPL. Otherwise, it’s usually better to type into a file and :load it.

The :type or :t command gives the type information for the specified value or function. It can give type information for any value or function in scope, whether it comes from the Prelude, a dependency, or declarations made directly in GHCi.

But :type can’t give you type information about types themselves.

The :info command can also give information about functions and operators.

With infix operators, the :info command helpfully tells you the precedence and fixity of the operator. infixl indicates left associativity, while the number after that indicates its precedence.

Quit a GHCi session using the :quit or :q command.