GHCi: the interactive shell

Contents
Start and quit
Load a file
Ask about types
Browse classes
Settings

Start and quit

GHCi reads one expression, evaluates it, prints the result, and waits. That loop is the fastest way to answer a question about the language without creating a file.

ghci

GHCi, version 9.10.1: https://www.haskell.org/ghc/ :? for help ghci> 2 + 2 4 ghci> :q Leaving GHCi.

A prompt starting with ghci> means the module Prelude is in scope, so the standard functions are available without an import.

Load a file

Save a definition to Main.hs, then load it with :l. The prompt changes to *Main>, which means the module is loaded with its internal names visible.

square :: Int -> Int square x = x * x

ghci Main.hs

ghci> square 12 144 ghci> :reload Ok, one module loaded.

:reload re-reads the file after an edit, so the editor and the prompt can stay open side by side.

Ask about types

:t prints the type of an expression without evaluating it. When a type error confuses you, ask for the type of the argument and the type of the function separately.

ghci> :t square square :: Int -> Int ghci> :t map map :: (a -> b) -> [a] -> [b] ghci> :t 42 42 :: Num a => a

The third answer says the literal works for any numeric type. GHCi defaults it to Integer when it prints a value, but the type stays general until something pins it down.

Browse classes

:i shows where a name comes from, its signature, and every instance of the class it belongs to. It answers which types can be compared faster than any documentation page.

ghci> :i Ord type Ord :: * -> Constraint class Eq a => Ord a where compare :: a -> a -> Ordering ... ghci> :i Bool data Bool = False | True

:? lists every command, and :browse Data.List prints the exports of a module you have imported.

Settings

Two flags make the prompt more useful. Multiline input lets you write a definition over several lines, and a shorter prompt leaves room for long expressions.

ghci -XMultiLineInput

ghci> :set prompt "> " > let twice f x = f (f x) > twice (+1) 5 7

Multiline input ends with an empty line, and a definition written this way lives only in the session. Anything you want to keep belongs in a file loaded with :l.

Next: Your first program

Article author: Arthur Isaev

Related articles
Haskell
Haskell course: zero to hero in 50 lessons
What is Haskell and why it matters
Install the toolchain with GHCup
GHCi: the interactive shell
Your first program
Values with let and where
Types and type signatures
Functions and application
Currying and partial application
Operators, sections, and fixity
if, guards, and pattern guards
case expressions
Pattern matching
Tuples
Lists
Ranges and enumeration
List comprehensions
Recursion replaces loops
map, filter, and foldr
Lambdas and composition
Type classes
Parametric polymorphism
Maybe and null safety
Either and recoverable errors
data: product types
data: sum types
Records
newtype and type synonyms
Recursive data: binary trees
Functor
Applicative
Monad
do notation
IO and purity
Files and IO
Modules and imports
Cabal projects
Dependencies
Testing with HUnit
Property testing with QuickCheck
Laziness and infinite lists
Strictness and space leaks
Folds
Monoids
Traversable
Monad transformers
Errors and exceptions
Concurrency
Parsing with Megaparsec
Capstone: a todo CLI
Hero roadmap: the whole course on one page
Banner image

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: