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
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
: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.
base such as
Data.Char are always available.
Many functions and types available in
base, such as
Data.Char, are not included in
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
length used above.
You can also declare custom types in the REPL. Notice the similarity in style of the declarations.
Declaring a constant value.
Declaring a function.
Declaring a type.
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
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
: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.
:type can’t give you type information about types themselves.
For that you may want
λ> :info Bool data Bool = False | True -- Defined in `GHC.Types' instance Eq Bool -- Defined in `GHC.Classes' instance Ord Bool -- Defined in `GHC.Classes' instance Show Bool -- Defined in `GHC.Show' instance Read Bool -- Defined in `GHC.Read' instance Enum Bool -- Defined in `GHC.Enum' instance Bounded Bool -- Defined in `GHC.Enum'
: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.