In your GHCi configurationGHC User’s Guide: The .ghci
files (sometimes called your “dot ghci file”), you can write GHCi commands that will run automatically every time you start GHCi.
Config file locations
GHCi reads config files from the following locations:
./.ghci
- Depending on the OS:
- Linux and macOS:
$HOME/.ghc/ghci.conf
- Windows:
C:\Documents and Settings\<username>\Application Data/ghc/ghci.conf
- Linux and macOS:
$HOME/.ghci
If more than one of these is present, then GHCi will run them all, in the order given above.
The first path ./.ghci
is relative to the current directory, so it can be useful for project-specific options. The latter two are where you keep configuration that you will use all the time. You can choose to put your configuration in either location, according to your preference.
Customizing your prompt
By default, the GHCi prompt looks like this:This style of multiline syntax, introduced by :{
and closed by :}
, is available in GHCi without any special settings.
Prelude> :{
Prelude| f :: Integer -> Integer
Prelude| f x = x + 1 Prelude| :}
It shows you what modules are imported, followed by >
on the first line of each command, and |
on any subsequent lines of a multi-line command. Often the module list ends up being obstrusively long, and so many people choose to set a different prompt. A popular choice is λ>
. You can do this by setting the prompt
and prompt-cont
variables in your GHCi config:
:set prompt "\x03BB> " :set prompt-cont " > "
Now your prompt will look like this:
λ> :{
> f :: Integer -> Integer
> f x = x + 1 > :}
You can also use ANSI escape codesAn ANSI escape code, supported by most common terminals, is a sequence of characters beginning with the ASCII escape character. These codes do a variety of things; the ones we use here signify changing the text color. to apply color. For example, to turn the prompt purple:
:set prompt "\ESC[1;35m\x03BB> \ESC[m" :set prompt-cont "\ESC[1;35m > \ESC[m"
Enabling language extensions
You can enable and disable GHC language extensions on the fly as you need them, but for extensions that you use very often, you may want to consider modifying your config to enable them by default.
For example, you might add something like this to your dot GHCi file, to enable these common basic extensions:See our recommended list of extensions for beginners.
:seti -XGADTSyntax
:seti -XGeneralizedNewtypeDeriving
:seti -XInstanceSigs
:seti -XLambdaCase
:seti -XPartialTypeSignatures
:seti -XScopedTypeVariables
:seti -XTypeApplications :seti -XOverloadedStrings
You can use :set
instead of :seti
,The :set
lesson will further discuss the difference between :set
and :seti
. but using :seti
ensures that the extensions you have turned on here don’t affect any modules you’re trying to load, which may use a different set of extensions, or none at all.
Enabling GHCi options
You can similarly enable GHCi options via your configuration file if you want them on all the time. For example, the :set +t
command is very useful for teaching; turning it on causes GHCi to automatically display the type of the last expression you evaluated, called it
in GHCi.
λ> print "hello world"
"hello world"
it :: ()
λ> 5 + 5
10
it :: Num a => a
λ> x = 5 + 5
x :: Num a => a
Notice on the last line it gives the type for x
instead of it
; that’s because x
hasn’t been evaluated yet, but x
does have a type! If you then call x
to evaluate it, the resulting type will be the same but will be given as the type of it
.
λ> x
10
it :: Num a => a
Incidentally, you can use it
as an argument to the next expression – it’s really handy if you’re ever inclined to use GHCi as a calculator!
λ> x = 5 + 5
x :: Num a => a
λ> x
10
it :: Num a => a
λ> it + 30
40
it :: Num a => a
λ> it + 20
60
it :: Num a => a
λ> it / 3
20.0
it :: Fractional a => a
Anything you can set with the :set
command can be turned on by default each time you open GHCi by putting it into your GHCi configuration. That includes things like -fdefer-type-errors
and -Wall
!
Disabling GHCi config
If you want to start a clean, standard GHCi that is unaffected by any configuration files, start GHCi with the -ignore-dot-ghci
flag.
$ ghci -ignore-dot-ghci
If you’re starting GHCi with Stack, it will look like this:
$ stack ghci --ghc-options -ignore-dot-ghci
Reading the source
If you’re curious about the details of how GHCi finds its config files, you can look at the source code for GHCi,The GHCi.UI module defines the loading of config files. which is located within the ghc
git repository.
To obtain the OS-specific location, it uses the getAppUserDataDirectory
getAppUserDataDirectory
function from the directory
The directory
package package, whose implementation (with some details omitted) looks like this:
getAppUserDataDirectoryInternal
has a different implementation depending on what operating system the package is built for. On a Unix platform, it looks like this:
And on Windows, it looks like this:
You can try using this function yourself and see what it returns for your system:
$ stack repl --package directory
λ> import System.Directory
λ> getAppUserDataDirectory "xyz"
"/home/chris/.xyz"
For historical reasons, GHCi does not follow the XDGXDG specifies a set of conventions for file paths. It has the advantage of allowing users to customize paths using environment variables, rather than forcing users to keep files in a particular location dictated by the program. Base Directory Specification, but it is recommended that you do so for new programs that you are writing. The directory
package supports this as well: Use getXdgDirectory
getXdgDirectory
instead of getAppUserDataDirectory
.
λ> getXdgDirectory XdgConfig "xyz"
"/home/chris/.config/xyz"