Table of Contents
There's a number of Haskell implementations available, of which two are in wide use. Hugs 98 is an interpreter that is primarily used for teaching. For real applications, the Glasgow Haskell Compiler, or GHC as it's usually known, is much more popular.
GHC has two complementary components: ghc, a compiler that generates native code, and ghci, an interpreter that can run either interactively or in “batch” mode.
Note | |
---|---|
When we discuss the package as a whole, we'll refer to it as GHC. If we're talking about one or another command, we'll mention either ghc or ghci. |
In this book, we assume that you're using at least version 6.6.1 of GHC. To obtain a copy of GHC for your platform, visit the GHC download page, and look for the list of binary packages. If you're using Windows or Mac OS X, these binary packages are the best ones to use.
Many Linux distributions, and BSD and other Unix variants, make pre-packaged versions of GHC available. Because they are built specifically for each environment, these packages are less hassle to use than the generic binary packages. You can find a list of such packages at the GHC distribution packages page.
We are providing the instructions below based on our experience installing GHC in mid-2007. Installation instructions inevitably become dated quickly; please bear this in mind as you read.
Because GHC runs on a large number of platforms, we've focused on a handful of the most popular.
The prebuilt binary packages of GHC should work on versions of Windows as old as ME, and on all newer versions (NT, 2000, XP, and Vista). We have installed GHC 6.6.1 under Windows XP Service Pack 2; here are the steps we followed.
Our first step is to visit the GHC download
page, and follow the link to the current stable
release. Scroll down to the section entitled “Binary
packages”, and then again to the subsection for
Windows. Download the installer; in our case, it's named
ghc-6.6.1-i386-windows.exe
.
After the installer has downloaded, double-clicking on it starts the installation process. This simply involves stepping through a normal Windows installer wizard.
Once the installer has finished, the Start Menu's “All Programs” submenu should have a GHC folder, inside of which you'll find an icon that you can double-click on to run ghci.
Clicking on the ghci icon brings up a normal Windows console window, running ghci.
Installing GHC on Mac OS X takes several steps, as GHC does not yet have a standard OS X installer. We have installed GHC 6.6.1 under Mac OS X 10.4, on an Intel-based MacBook. We're not regular Mac users, and had never tried installing GHC on OS X before, and everything worked for us on the first try, so take heart if these instructions seem daunting. The process is neither difficult nor especially time-consuming.
Our first step is to visit the GHC download page, and follow the link to the current stable release. Scroll down to the section entitled “Binary packages”, and then again to the subsection for Mac OS X. There are four components to download, all of which are necessary.
Apple's Xcode development software. This provides compiler toolchain support that GHC needs.
The GNUreadline
framework
provides flexible command line editing.
The GMP
framework is required for
arbitrary-precision integer support.
The GHC package itself. This will not work unless both of the preceding frameworks are installed.
The Xcode software installer may have come bundled on a DVD with your Mac. If not (or you can't find it), you can download it from Apple and install it. Once you've finished installing Xcode, continue on to download the remaining three packages.
After these downloads complete, you'll have three archive icons on your desktop.
Double click on each one to unpack it, giving you three folders.
Open a Finder window with
command-n. In the left sidebar, click on your system's main
hard disk icon (often named “Macintosh HD”). In
the main portion of the window, double click on
System
to open that folder, then on
Library
. Select the
GMP.framework
and
GNUreadline.framework
folders on your
desktop, and drag them onto the
Frameworks
folder in the Finder window
that is visiting /System/Library
. If the
Finder refuses to install them because you don't have
permission, it will probably display an
“Authenticate” button in the alert it displays.
Click it, enter your password, and installation can
proceed.
With the prerequisites in place, you can turn to
installing GHC. You'll need to open a Terminal window (you
can find it in
/Applications/Utilities
).
Note | |
---|---|
Since most of your interactions with GHC will be through a Terminal window, this might be a good time to add the Terminal application to your dock, if you haven't already done so. |
Inside the Terminal window, change directory to
Desktop/ghc-6.6.1
, and run
./configure
to set up the command line
installer. This configures GHC to install to
/usr/local
. When the
configure script finishes, run
sudo make install
, and type your
password when you are prompted for it.
The installation process should take a minute or
two. If you don't already have
/usr/local/bin
in your shell's search
path, add it.
Finally, you should be able to successfully run the ghci command from your shell prompt.
GHC is packaged for Fedora. From a shell, all you need
to do is run sudo yum -y install ghc ghc-doc
ghc661-prof
. The base package, containing the
ghc and ghci commands and libraries, is
ghc
. The ghc-doc
package contains the GHC user guide, and command and library
documentation. The ghc661-prof
package
contains profiling-capable versions of the standard libraries
(note: its version number may have changed by the time you
read this).
Once installation has finished, you should be able to run ghci from the shell immediately. You won't need to change your shell's search path, or set any environment variables.
The interactive interpreter for GHC is a program named ghci. It lets you enter and evaluate Haskell expressions, and explore modules and type information.
When we run ghci, it displays a startup banner, followed
by a Prelude>
prompt.
$ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.1, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Prelude>$
ghci
___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.1, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done.Prelude>
On most systems, ghci has some amount of command line editing ability. On Unix-like systems, it uses the GNU readline library, which is powerful and customisable. On Windows, ghci's command line editing capabilities are provided by the doskey command.
If you haven't used command line editing before, it's a huge time saver. The basics are common to both Unix-like and Windows systems. Pressing the up arrow key on your keyboard recalls the last line of input you entered; pressing up repeatedly cycles through earlier lines of input. You can use the left and right arrow keys to move around inside a line of input.
Just knowing this much will save you a lot of repeated typing. If you want to learn more about command line editing on your system, consult the readline or doskey documentation.
Where some people might run a calculator program, I often drop into ghci to perform simple calculations. Using it this way serves as a good way to become familiar with ghci itself, and with the basics of Haskell expressions.
We can immediately start typing expressions, to see what ghci will do with them. Basic arithmetic works as we'd expect.
ghci> 2 + 2 4 ghci> 31337 * 101 3165037 ghci> 7/2 3.5ghci>
2 + 2
4ghci>
31337 * 101
3165037ghci>
7/2
3.5
As the expressions above imply, Haskell has a notion of
integers and floating point numbers. In fact, it allows us to
use arbitrarily large integers. Here, the
(^)
is the exponentiation
operator.
ghci> 31337 ^ 15 27596961266048865189478071639245914618921288733595362747095073723993ghci>
31337 ^ 15
27596961266048865189478071639245914618921288733595362747095073723993
Like other languages that use infix notation to write mathematical expressions, Haskell has a notion of operator precedence. This allows us to get rid of a few parentheses. For example, the multiplication operator has a higher precedence than the addition operator, so Haskell treats the two following expressions as equivalent.
ghci> (4 * 4) + 1 17 ghci> 4 * 4 + 1 17ghci>
(4 * 4) + 1
17ghci>
4 * 4 + 1
17
Haskell presents us with one peculiarity in how we must write numbers: it's often necessary to enclose a negative number in parentheses. This affects us as soon as we move past writing the simplest of expressions.
ghci> -3 -3 ghci> 2 + -3 <interactive>:1:0: precedence parsing error cannot mix `(+)' [infixl 6] and prefix `-' [infixl 6] in the same infix expression ghci> 2 + (-3) -1ghci>
-3
-3ghci>
2 + -3
<interactive>:1:0: precedence parsing error cannot mix `(+)' [infixl 6] and prefix `-' [infixl 6] in the same infix expressionghci>
2 + (-3)
-1
Later on, we'll be seeing how Haskell lets us devise entirely new infix operators. Now that we've been forewarned, the following may not prove too surprising.
Most of the time, we can omit whitespace from expressions, and Haskell will parse them as we intended. But not always. Here's an expression that works:
ghci> 2+3 5ghci>
2+3
5
And here's one that similar to the problematic negative number example above, but results in a different error message.
ghci> 2+-3 <interactive>:1:1: Not in scope: `+-'ghci>
2+-3
<interactive>:1:1: Not in scope: `+-'
What's happening here is that the Haskell parser is
reading +-
as a single token, and trying to
use it as an operator. Once again, a few parentheses get us
and ghci looking at the expression in the same way.
ghci> 2+(-3) -1ghci>
2+(-3)
-1
Compared to other languages, this unusual treatment of negative numbers is an annoyance, for sure, but it at least represents a reasoned tradeoff. As we mentioned, Haskell lets us define new operators at any time, and choose the precedence and associativity of those operators. The language designers chose to accept a slightly cumbersome syntax for negative numbers in exchange for this expressive power.
ghci defines at least one well-known mathematical constant for us.
ghci> pi 3.141592653589793ghci>
pi
3.141592653589793
But its coverage of mathematical constants is not great,
as we can quickly see. Let's see if Euler's number,
e
, is available.
ghci> e <interactive>:1:0: Not in scope: `e'ghci>
e
<interactive>:1:0: Not in scope: `e'
Note | |
---|---|
If the above “not in scope” error message
seems a little daunting, don't worry. All it means is that
there is no variable defined with the name
|
We can define e
ourselves; the let
construct allows us to introduce a new variable.
ghci> let e = 2.7182818284590451ghci>
let e = 2.7182818284590451
We can then use our definition of e
in
arithmetic expressions.
ghci> (e ** pi) - pi 19.99909997918947ghci>
(e ** pi) - pi
19.99909997918947
Haskell gives us the usual operators for working with boolean values.
ghci> True True ghci> False False ghci> True && False False ghci> False || True Trueghci>
True
Trueghci>
False
Falseghci>
True && False
Falseghci>
False || True
True
Unlike some other languages, Haskell does not treat the
number zero as synonymous with False
, nor
does it accept non-zero as True
.
ghci> True && 1 <interactive>:1:8: No instance for (Num Bool) arising from the literal `1' at <interactive>:1:8 Possible fix: add an instance declaration for (Num Bool) In the second argument of `(&&)', namely `1' In the expression: True && 1 In the definition of `it': it = True && 1ghci>
True && 1
<interactive>:1:8: No instance for (Num Bool) arising from the literal `1' at <interactive>:1:8 Possible fix: add an instance declaration for (Num Bool) In the second argument of `(&&)', namely `1' In the expression: True && 1 In the definition of `it': it = True && 1
Comparison operators are mostly familiar from other languages.
ghci> 1 == 1 True ghci> 2 < 3 True ghci> 4 >= 3.99 Trueghci>
1 == 1
Trueghci>
2 < 3
Trueghci>
4 >= 3.99
True
There's one exception: the “is not equal”
operator is (/=)
.
ghci> 2 /= 3 Trueghci>
2 /= 3
True
In addition to integers and floating point numbers,
Haskell supports rational numbers. Haskell coders collect
self-contained hunks of code into
modules. The integer and floating point
numbers, and the operators we've seen so far, are packaged in
a module named Prelude
.
(The Prelude
module
is often referred to as “the standard prelude”,
because its contents are defined by the Haskell 98 standard.
Sometimes, it's simply shortened to “the
prelude”.)
The prelude is always implicitly available; we don't need
to take any actions to use the types, values, or functions it
defines. But to use definitions from other modules, we must
import them. To use rational numbers,
the module we need to import is named Data.Ratio
. We can use a ghci
directive named :module
to import
it.
ghci> :module Data.Ratioghci>
:module Data.Ratio
The notation for writing a rational number is as follows.
ghci> 7 % 2 7%2ghci>
7 % 2
7%2
The (%)
operator above takes two
integers and constructs a rational number from them.
Arithmetic on rational numbers works in the same way as on other types of number, even allowing the same operators.
ghci> 7 % 2 + 2 % 3 25%6ghci>
7 % 2 + 2 % 3
25%6
Haskell represents a rational number with the lowest
denominator it can. For example, the result of the following
expression is simplified from 254%7
to
something easier to read.
ghci> (22 % 7) * 7 22%1ghci>
(22 % 7) * 7
22%1
Is it too early to introduce this? Does it disrupt the flow?
We've already seen an exponentiation operator in Haskell:
(^)
raises a number to an integer power.
The word integer is significant here: if
we try to raise a number to the power of a floating point
number using the (^)
operator, exciting
things will happen.
ghci> 12 ^ 2 144 ghci> 12.1 ^ 2 146.41 ghci> 12 ^ 2.1 <interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from use of `^' at <interactive>:1:0-7 `Fractional t' arising from the literal `2.1' at <interactive>:1:5-7 Probable fix: add a type signature that fixes these type variable(s)ghci>
12 ^ 2
144ghci>
12.1 ^ 2
146.41ghci>
12 ^ 2.1
<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from use of `^' at <interactive>:1:0-7 `Fractional t' arising from the literal `2.1' at <interactive>:1:5-7 Probable fix: add a type signature that fixes these type variable(s)
Notice from the second example that it doesn't matter whether or not the base is an integer, only that the exponent must be.
There's a further constraint on the exponent that is not immediately obvious: it must be not just an integer, but a non-negative integer.
ghci> 12 ^ 2 144 ghci> 12 ^ (-2) *** Exception: Prelude.^: negative exponentghci>
12 ^ 2
144ghci>
12 ^ (-2)
*** Exception: Prelude.^: negative exponent
If you think about the simplest definition of exponentiation, which is a number repeatedly multiplied by itself a given number of times, this restriction makes sense.
Haskell's exponentiation operator follows the convention that a number raised to the zeroth power is one. This is why the restriction on the exponent is that it must be non-negative, and not that it must be positive.
ghci> 12 ^ 0 1ghci>
12 ^ 0
1
Haskell also provides a generalised integer exponentiation
operator, (^^)
. This accepts both
positive and negative exponents, following the rule that a
number raised to a negative exponent is the reciprocal of the
number raised to the positive exponent. Let's try this with
both integer and rational bases.
ghci> 12 ^^ (-2) 6.944444444444444e-3 ghci> (12%1) ^^ (-2) 1%144ghci>
12 ^^ (-2)
6.944444444444444e-3ghci>
(12%1) ^^ (-2)
1%144
Finally, Haskell also gives us a floating point
exponentiation operator, (**)
.
ghci> 12.2 ** 2.1 191.1417880875707ghci>
12.2 ** 2.1
191.1417880875707
Remember the point we made earlier about explicit parentheses often being good? Here's an example of that idea in action, except here the parentheses are necessary, not merely a good idea.
ghci> 22 % 7 * 7 % 22 <interactive>:1:0: No instance for (Integral (Ratio t)) arising from use of `%' at <interactive>:1:0-16 Possible fix: add an instance declaration for (Integral (Ratio t)) In the expression: ((22 % 7) * 7) % 22 In the definition of `it': it = ((22 % 7) * 7) % 22ghci>
22 % 7 * 7 % 22
<interactive>:1:0: No instance for (Integral (Ratio t)) arising from use of `%' at <interactive>:1:0-16 Possible fix: add an instance declaration for (Integral (Ratio t)) In the expression: ((22 % 7) * 7) % 22 In the definition of `it': it = ((22 % 7) * 7) % 22
Look at that error message; it's detailed, and mentions a lot of concepts we haven't covered yet. We're new to Haskell! How are we supposed to interpret all of that? The first thing we must do is take a deep breath and not worry about the details.
If we step back and gloss over the error message, we can see that ghci is displaying for us the expression that it had trouble with. And it has helpfully added parentheses back into the expression, only look! They're in the wrong places
This isn't the fault of ghci. It just happens that the
(%)
and (*)
operators
have the same precedences, so ghci parses the expession from
left to right. As a result, it tries to construct a rational
from another rational and an integer, instead of from a pair of
integers. (If (%)
had a higher precedence
than (*)
, the expression would be parsed
the way we might have hoped.)
All we have to do to correct this problem is add some explicit parentheses to say what we really mean.
ghci> (22 % 7) * (7 % 22) 1%1ghci>
(22 % 7) * (7 % 22)
1%1
If you are familiar with a language like Python, you'll find Haskell's notations for strings, lists and tuples familiar.
A text string is surrounded by double quotes.
ghci> "This is a string." "This is a string."ghci>
"This is a string."
"This is a string."
As in many languages, we can represent hard-to-print characters by “escaping” them. Haskell's escape characters and escaping rules expand on the conventions established by the C language (for details, see Appendix A, Characters, strings, and escaping rules).
ghci> "Here's a newline -->\n<-- See?" "Here's a newline -->\n<-- See?"ghci>
"Here's a newline -->\n<-- See?"
"Here's a newline -->\n<-- See?"
A list is surrounded by square brackets, with elements separated by commas.
ghci> [1, 2, 3] [1,2,3]ghci>
[1, 2, 3]
[1,2,3]
ghci> [] [] ghci> ["foo", "bar", "baz", "quux", "fnord", "xyzzy"] ["foo","bar","baz","quux","fnord","xyzzy"]ghci>
[]
[]ghci>
["foo", "bar", "baz", "quux", "fnord", "xyzzy"]
["foo","bar","baz","quux","fnord","xyzzy"]
All elements of a list must have the same type.
ghci> [1, 2, "buckle my shoe"] <interactive>:1:1: No instance for (Num [Char]) arising from the literal `1' at <interactive>:1:1 Possible fix: add an instance declaration for (Num [Char]) In the expression: 1 In the expression: [1, 2, "buckle my shoe"] In the definition of `it': it = [1, 2, "buckle my shoe"]ghci>
[1, 2, "buckle my shoe"]
<interactive>:1:1: No instance for (Num [Char]) arising from the literal `1' at <interactive>:1:1 Possible fix: add an instance declaration for (Num [Char]) In the expression: 1 In the expression: [1, 2, "buckle my shoe"] In the definition of `it': it = [1, 2, "buckle my shoe"]
Once again, ghci's error message is verbose, but it's simply telling us that it can't figure out how to turn the string into a number, so the list isn't properly typed.
When it makes sense to do so, we can write a range of elements, and Haskell will fill in the contents of the list for us.
ghci> [1..10] [1,2,3,4,5,6,7,8,9,10]ghci>
[1..10]
[1,2,3,4,5,6,7,8,9,10]
We can specify the size of the step to use by giving the first two elements, followed by the value at which to stop generating the range.
ghci> [1.0,1.25..2.0] [1.0,1.25,1.5,1.75,2.0] ghci> [1,4..15] [1,4,7,10,13]ghci>
[1.0,1.25..2.0]
[1.0,1.25,1.5,1.75,2.0]ghci>
[1,4..15]
[1,4,7,10,13]
Haskell makes a distinction between single characters and text strings. A single character is enclosed in single quotes.
ghci> 'a' 'a'ghci>
'a'
'a'
In fact, a text string is simply a list of individual characters. Here's a painful way to write a short string, which ghci gives back to us in a more familiar form.
ghci> let a = ['l', 'o', 't', 's', ' ', 'o', 'f', ' ', 'w', 'o', 'r', 'k'] ghci> a "lots of work" ghci> a == "lots of work" Trueghci>
let a = ['l', 'o', 't', 's', ' ', 'o', 'f', ' ', 'w', 'o', 'r', 'k']
ghci>
a
"lots of work"ghci>
a == "lots of work"
True
Despite all our talk of types, our interactions with ghci have so far been free of much type-related thinking. We haven't told ghci what types we've been using, and it's mostly been willing to accept our input.
The first thing we can do to start explicitly exploring the world of types is to get ghci to tell us more about what it's doing. ghci has a command, :set, that lets us change a few of its default behaviours. We can tell it to print more type information as follows.
ghci> :set +t ghci> 'c' 'c' it :: Char ghci> "foo" "foo" it :: [Char]ghci>
:set +t
ghci>
'c'
'c' it :: Charghci>
"foo"
"foo" it :: [Char]
What the +t
does is tell ghci to print the
type of an expression after the expression. That cryptic
it
in the output can be very useful: it's
actually the name of a special variable, in which ghci stores
the result of the last expression we evaluated. Let's break
down the meaning of the last line of ghci output, then.
Here are a few more of Haskell's names for types, from expressions of the sort we've already seen.
ghci> 7 ^ 80 40536215597144386832065866109016673800875222251012083746192454448001 it :: Integerghci>
7 ^ 80
40536215597144386832065866109016673800875222251012083746192454448001 it :: Integer
Integer is Haskell's arbitrary-precision integer type.
Rational numbers don't look quite the same as integers.
ghci> 11 % 29 11%29 it :: Ratio Integerghci>
11 % 29
11%29 it :: Ratio Integer
Notice two words on the right hand side
of the ::
above. We can read this as a
Ratio of Integer, and infer that a
Ratio will probably need to have values of type
Integer as both numerator and denominator. Sure
enough, if we try to construct a Ratio where the
numerator and denominator are of different types, ghci
complains.
ghci> 3.14 % 8 <interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from use of `%' at <interactive>:1:0-7 `Fractional t' arising from the literal `3.14' at <interactive>:1:0-3 Probable fix: add a type signature that fixes these type variable(s)ghci>
3.14 % 8
<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from use of `%' at <interactive>:1:0-7 `Fractional t' arising from the literal `3.14' at <interactive>:1:0-3 Probable fix: add a type signature that fixes these type variable(s)
Although it's initially useful to have :set
+t
giving us type information for every expression
we enter, this is a facility we'll quickly outgrow, simply
because it will become redundant: after a while, we'll often
know what type we expect an expression to have, so why get
ghci to remind us? We can turn off the extra type information
at any time.
ghci> :set -t unrecognised flags: -t ghci> 2 2 it :: Integerghci>
:set -t
unrecognised flags: -tghci>
2
2 it :: Integer
Even with this facility turned off, we can still get that type information easily when we need it, using another ghci command.
ghci> :type 22 % 7 22 % 7 :: (Integral t) => Ratio t ghci> "foo" "foo" it :: [Char] ghci> :type it it :: [Char]ghci>
:type 22 % 7
22 % 7 :: (Integral t) => Ratio tghci>
"foo"
"foo" it :: [Char]ghci>
:type it
it :: [Char]
The :type command will print type
information for any expression we give it (including
it
, as we see above). It won't actually
evaluate the expression; it only checks its type and prints
that.
In this chapter, we've seen how to install GHC for our environment. We then went on to interactively explore some basic Haskell concepts using ghci the interpreter bundled with GHC. We saw how to evaluate simple expressions.
We dipped a toe into the water of typing.
We also had drilled into us the notion that we don't need to understand, or be intimidated by, every single gripe that ghci throws our way. We'll do just fine with a shallow understanding initially, and rely on practice and more reading to round out our knowledge. Onwards!