As with all known Haskell systems, GHC implements some extensions to
the language. To use them, you'll need to give a -fglasgow-exts
option.

Virtually all of the Glasgow extensions serve to give you access to
the underlying facilities with which we implement Haskell. Thus, you
can get at the Raw Iron, if you are willing to write some non-standard
code at a more primitive level. You need not be “stuck” on
performance because of the implementation costs of Haskell's
“high-level” features—you can always code “under” them. In an extreme case, you can write all your time-critical code in C, and then just glue it together with Haskell!

Executive summary of our extensions:

Unboxed types and primitive operations:

You can get right down to the raw machine types and
operations; included in this are “primitive
arrays” (direct access to Big Wads of Bytes). Please
see Section 7.2.1 and following.

Type system extensions:

GHC supports a large number of extensions to Haskell's
type system. Specifically:

Scoped type variables enable the programmer to
supply type signatures for some nested declarations,
where this would not be legal in Haskell 98. Details in
Section 7.14.

Pattern guards

Instead of being a boolean expression, a guard is a list
of qualifiers, exactly as in a list comprehension. See Section 7.5.

Parallel list comprehensions

An extension to the list comprehension syntax to support
zipWith-like functionality. See Section 7.6.

Foreign calling:

Just what it sounds like. We provide
lots of rope that you can dangle around
your neck. Please see Chapter 8.

Pragmas

Pragmas are special instructions to the compiler placed
in the source file. The pragmas GHC supports are described in
Section 7.15.

Rewrite rules:

The programmer can specify rewrite rules as part of the
source program (in a pragma). GHC applies these rewrite rules
wherever it can. Details in Section 7.16.

Generic classes:

Generic class declarations allow you to define a class
whose methods say how to work over an arbitrary data type.
Then it's really easy to make any new type into an instance of
the class. This generalises the rather ad-hoc "deriving"
feature of Haskell 98. Details in Section 7.17.

Before you get too carried away working at the lowest level (e.g.,
sloshing MutableByteArray#s around your
program), you may wish to check if there are libraries that provide a
“Haskellised veneer” over the features you want. See
Haskell Libraries.

GHC normally imports
Prelude.hi files for you. If you'd
rather it didn't, then give it a
-fno-implicit-prelude option. The idea
is that you can then import a Prelude of your own. (But
don't call it Prelude; the Haskell
module namespace is flat, and you must not conflict with
any Prelude module.)

Even though you have not imported the Prelude, all
the built-in syntax still refers to the built-in Haskell
Prelude types and values, as specified by the Haskell
Report. For example, the type [Int]
still means Prelude.[] Int; tuples
continue to refer to the standard Prelude tuples; the
translation for list comprehensions continues to use
Prelude.map etc.

With one group of exceptions! You may want to
define your own numeric class hierarchy. It completely
defeats that purpose if the literal "1" means
"Prelude.fromInteger 1", which is what
the Haskell Report specifies. So the
-fno-implicit-prelude flag causes the
following pieces of built-in syntax to refer to whatever
is in scope, not the Prelude versions:

Integer and fractional literals mean
"fromInteger 1" and
"fromRational 3.2", not the
Prelude-qualified versions; both in expressions and in
patterns.

Negation (e.g. "- (f x)")
means "negate (f x)" (not
Prelude.negate).

In an n+k pattern, the standard Prelude
Ord class is still used for comparison,
but the necessary subtraction uses whatever
"(-)" is in scope (not
"Prelude.(-)").

Note: Negative literals, such as -3, are
specified by (a careful reading of) the Haskell Report as
meaning Prelude.negate (Prelude.fromInteger 3).
However, GHC deviates from this slightly, and treats them as meaning
fromInteger (-3). One particular effect of this
slightly-non-standard reading is that there is no difficulty with
the literal -2147483648 at type Int;
it means fromInteger (-2147483648). The strict interpretation
would be negate (fromInteger 2147483648),
and the call to fromInteger would overflow
(at type Int, remember).