GHC's behaviour is firstly controlled by a mode flag. Only one of these flags may be given, but it does not necessarily need to be the first option on the command-line. The available modes are:
ghc --interactive
Interactive mode, which is also available as ghci. Interactive mode is described in more detail in Chapter 3, Using GHCi.
ghc --make
In this mode, GHC will build a multi-module Haskell
program automatically, figuring out dependencies for itself.
If you have a straightforward Haskell program, this is
likely to be much easier, and faster, than using
make. Make mode is described in Section 5.4.1, “Using ghc ––make”.
ghc -e expr
Expression-evaluation mode. This is very similar to
interactive mode, except that there is a single expression
to evaluate (expr) which is given
on the command line. See Section 5.4.2, “Expression evaluation mode” for
more details.
ghc -E ghc -c ghc -S ghc -c
This is the traditional batch-compiler mode, in which GHC can compile source files one at a time, or link objects together into an executable. This mode also applies if there is no other mode flag specified on the command line, in which case it means that the specified files should be compiled and then linked to form a program. See Section 5.4.3, “Batch compiler mode”.
ghc -M
Dependency-generation mode. In this mode, GHC can be
used to generate dependency information suitable for use in
a Makefile. See Section 5.6.11, “Dependency generation”.
ghc --mk-dll
DLL-creation mode (Windows only). See Section 12.6.1, “Creating a DLL”.
ghc --help ghc -?
Cause GHC to spew a long usage message to standard output and then exit.
ghc --show-iface file
Read the interface in
file and dump it as text to
stdout. For example ghc --show-iface M.hi.
ghc --supported-languages
Print the supported language extensions.
ghc --info
Print information about the compiler.
ghc --version ghc -V
Print a one-line string including GHC's version number.
ghc --numeric-version
Print GHC's numeric version number only.
ghc --print-libdir
Print the path to GHC's library directory. This is
the top of the directory tree containing GHC's libraries,
interfaces, and include files (usually something like
/usr/local/lib/ghc-5.04 on Unix). This
is the value of
$libdir
in the package configuration file
(see Section 5.8, “
Packages
”).
When given the ––make option,
GHC will build a multi-module Haskell program by following
dependencies from one or more root modules (usually just
Main). For example, if your
Main module is in a file called
Main.hs, you could compile and link the
program like this:
ghc ––make Main.hs
The command line may contain any number of source file
names or module names; GHC will figure out all the modules in
the program by following the imports from these initial modules.
It will then attempt to compile each module which is out of
date, and finally, if there is a Main module,
the program will also be linked into an executable.
The main advantages to using ghc
––make over traditional
Makefiles are:
GHC doesn't have to be restarted for each compilation,
which means it can cache information between compilations.
Compiling a multi-module program with ghc
––make can be up to twice as fast as
running ghc individually on each source
file.
You don't have to write a Makefile.
GHC re-calculates the dependencies each time it ismas">Section 8.12.5, “INLINE and NOINLINE pragmas”.
The INLINE pragma affects the specialised version of the
function (only), and applies even if the function is recursive. The motivating
example is this:
-- A GADT for arrays with type-indexed representation
data Arr e where
ArrInt :: !Int -> ByteArray# -> Arr Int
ArrPair :: !Int -> Arr e1 -> Arr e2 -> Arr (e1, e2)
(!:) :: Arr e -> Int -> e
{-# SPECIALISE INLINE (!:) :: Arr Int -> Int -> Int #-}
{-# SPECIALISE INLINE (!:) :: Arr (a, b) -> Int -> (a, b) #-}
(ArrInt _ ba) !: (I# i) = I# (indexIntArray# ba i)
(ArrPair _ a1 a2) !: i = (a1 !: i, a2 !: i)
Here, (!:) is a recursive function that indexes arrays
of type Arr e. Consider a call to (!:)
at type (Int,Int). The second specialisation will fire, and
the specialised function will be inlined. It has two calls to
(!:),
both at type Int. Both these calls fire the first
specialisation, whose body is also inlined. The result is a type-based
unrolling of the indexing function.
Warning: you can make GHC diverge by using SPECIALISE INLINE
on an ordinarily-recursive function.
Note: In earlier versions of GHC, it was possible to provide your own specialised function for a given type:
{-# SPECIALIZE hammeredLookup :: [(Int, value)] -> Int -> value = intLookup #-}
This feature has been removed, as it is now subsumed by the
RULES pragma (see Section 8.13.4, “Specialisation
”).
Same idea, except for instance declarations. For example:
instance (Eq a) => Eq (Foo a) where {
{-# SPECIALIZE instance Eq (Foo [(Int, Bar)]) #-}
... usual stuff ...
}
The pragma must occur inside the where part
of the instance declaration.
Compatible with HBC, by the way, except perhaps in the placement of the pragma.
The UNPACK indicates to the compiler
that it should unpack the contents of a constructor field into
the constructor itself, removing a level of indirection. For
example:
data T = T {-# UNPACK #-} !Float
{-# UNPACK #-} !Float
will create a constructor T containing
two unboxed floats. This may not always be an optimisation: if
the T constructor is scrutinised and the
floats passed to a non-strict function for example, they will
have to be reboxed (this is done automatically by the
compiler).
Unpacking constructor fields should only be used in
conjunction with -O, in order to expose
unfoldings to the compiler so the reboxing can be removed as
often as possible. For example:
f :: T -> Float f (T f1 f2) = f1 + f2
The compiler will avoid reboxing f1
and f2 by inlining +
on floats, but only when -O is on.
Any single-constructor data is eligible for unpacking; for example
data T = T {-# UNPACK #-} !(Int,Int)
will store the two Ints directly in the
T constructor, by flattening the pair.
Multi-level unpacking is also supported:
data T = T {-# UNPACK #-} !S
data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
will store two unboxed Int#s
directly in the T constructor. The
unpacker can see through newtypes, too.
If a field cannot be unpacked, you will not get a warning,
so it might be an idea to check the generated code with
-ddump-simpl.
See also the -funbox-strict-fields flag,
which essentially has the effect of adding
{-# UNPACK #-} to every strict
constructor field.