Table of Contents
As you read the early chapters of this book, keep in mind that we will sometimes introduce ideas in restricted, simplified form. Haskell is a deep language, and presenting every aspect of a given subject all at once is likely to prove overwhelming. As we build a solid foundation in Haskell, we will expand upon these initial explanations.
Haskell is a language with many implementations, of which two are in wide use. Hugs is an interpreter that is primarily used for teaching. For real applications, the Glasgow Haskell Compiler (GHC) is much more popular. Compared to Hugs, GHC is more suited to “real work”: it compiles to native code, supports parallel execution, and provides useful performance analysis and debugging tools. For these reasons, GHC is the Haskell implementation that we will be using throughout this book.
|How we refer to the components of GHC|
In this book, we assume that you're using at least version 6.8.2 of GHC, which was released in 2007. Many of our examples will work unmodified with older versions. However, we recommend using the newest version available for your platform. If you're using Windows or Mac OS X, you can get started easily and quickly using a prebuilt installer. To obtain a copy of GHC for these platforms, visit the GHC download page, and look for the list of binary packages and installers.
Many Linux distributors, and providers of BSD and other Unix variants, make custom binary packages of GHC available. Because these are built specifically for each environment, they are much easier to install and use than the generic binary packages that are available from the GHC download page. You can find a list of distributions that custom-build GHC at the GHC distribution packages page.
For more detailed information about how to install GHC on a variety of popular platforms, we've provided some instructions in Appendix A, Installing GHC and Haskell libraries.
The interactive interpreter for GHC is a program
named ghci. It lets us enter and evaluate Haskell
expressions, explore modules, and debug our code. If you are
familiar with Python or Ruby, ghci is somewhat similar to
interactive Python and Ruby interpreters.
|The ghci command has a narrow focus|
We typically cannot copy some code out of a Haskell source file and paste it into ghci. This does not have a significant effect on debugging pieces of code, but it can initially be surprising if you are used to, say, the interactive Python interpreter.
On Unix-like systems, we run ghci as a command in a shell window. On Windows, it's available via the Start Menu. For example, if you installed using the GHC installer on Windows XP, you should go to “All Programs”, then “GHC”; you will then see ghci in the list. (See the section called “Windows” for a screenshot.)
ghciGHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done.
Prelude in the prompt
standard library of useful functions, is loaded and ready to
use. When we load other modules or source files, they will show
up in the prompt, too.
|About the ghci prompt|
The prelude is always implicitly available; we don't need to take any actions to use the types, values, or functions it defines. To use definitions from other modules, we must load them into ghci, using the :module command.
:module + Data.Ratio
In addition to providing a convenient interface for testing code fragments, ghci can function as a readily accessible desktop calculator. We can easily express any calculator operation in ghci and, as an added bonus, we can add more complex operations as we become more familiar with Haskell. Even using the interpreter in this simple way can help us to become more comfortable with how Haskell works.
We can immediately start entering expressions, to see what ghci will do with them. Basic arithmetic works similarly to languages like C and Python: we write expressions in infix form, where an operator appears between its operands.
2 + 24
31337 * 1013165037
7.0 / 2.03.5
The infix style of writing an expression is just a convenience: we can also write an expression in prefix form, where the operator precedes its arguments. To do this, we must enclose the operator in parentheses.
2 + 24
(+) 2 24
313 ^ 1527112218957718876716220410905036741257
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 beyond the simplest expressions.
- above is a unary operator. In other
words, we didn't write the single number “-3”; we
wrote the number “3”, and applied the operator
- to it. The
- operator is
Haskell's only unary operator, and we cannot mix it with infix
2 + -3<interactive>:1:0: precedence parsing error cannot mix `(+)' [infixl 6] and prefix `-' [infixl 6] in the same infix expression
2 + (-3)-1
3 + (-(13 * 37))-478
This avoids a parsing ambiguity. When we apply a function
in Haskell, we write the name of the function, followed by its
argument, for example
f 3. If we did not need to
wrap a negative number in parentheses, we would have two
profoundly different ways to read
f-3: it could
be either “apply the function
-3”, or “subtract the
3 from the variable
2*-3<interactive>:1:1: Not in scope: `*-'
Here, the Haskell implementation is reading
*- as a single operator. Haskell lets us
define new operators (a subject that we will return to later),
but we haven't defined
*-. Once again, a
few parentheses get us and ghci looking at the expression in
the same way.
Compared to other languages, this unusual treatment of negative numbers might seem annoying, but it represents a reasoned trade-off. Haskell lets us define new operators at any time. This is not some kind of esoteric language feature; we will see quite a few user-defined operators in the chapters ahead. The language designers chose to accept a slightly cumbersome syntax for negative numbers in exchange for this expressive power.
The values of Boolean logic in Haskell are
False. The capitalization of these names is
important. The language uses C-influenced operators for
working with Boolean values:
is logical “and”, and
is logical “or”.
True && FalseFalse
False || TrueTrue
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
Once again, we are faced with a
substantial-looking error message. In brief, it tells us that
the Boolean type, Bool, is not a member of the
family of numeric types,
Num. The error message
is rather long because ghci is pointing out the location of
the problem, and hinting at a possible change we could make
that might fix the problem.
|Remain fearless in the face of error messages|
We have an important point to make here, which we will repeat throughout the early sections of this book. If you run into problems or error messages that you do not yet understand, don't panic. Early on, all you have to do is figure out enough to make progress on a problem. As you acquire experience, you will find it easier to understand parts of error messages that initially seem obscure.
The numerous error messages have a purpose: they actually help us in writing correct code, by making us perform some amount of debugging “up front”, before we ever run a program. If you are coming from a background of working with more permissive languages, this way of working may come as something of a shock. Bear with us.
1 == 1True
2 < 3True
4 >= 3.99True
2 /= 3True
Like written algebra and other programming languages that use infix operators, Haskell has a notion of operator precedence. We can use parentheses to explicitly group parts of an expression, and precedence allows us to omit a few parentheses. For example, the multiplication operator has a higher precedence than the addition operator, so Haskell treats the following two expressions as equivalent.
1 + (4 * 4)17
1 + 4 * 417
Haskell assigns numeric precedence values to operators, with 1 being the lowest precedence and 9 the highest. A higher-precedence operator is applied before a lower-precedence operator. We can use ghci to inspect the precedence levels of individual operators, using its :info command.
:info (+)class (Eq a, Show a) => Num a where (+) :: a -> a -> a ... -- Defined in GHC.Num infixl 6 +
:info (*)class (Eq a, Show a) => Num a where ... (*) :: a -> a -> a ... -- Defined in GHC.Num infixl 7 *
The information we seek is in the line
infixl 6 +”, which indicates that
(+) operator has a precedence of 6.
(We will explain the other output in a later chapter.)
infixl 7 *” tells us that the
(*) operator has a precedence of 7. Since
(*) has a higher precedence than
(+), we can now see why
1 + 4 *
4 is evaluated as
1 + (4 * 4), and not
(1 + 4) * 4.
Haskell also defines associativity of
operators. This determines whether an expression containing
multiple uses of an operator is evaluated from left to right, or
right to left. The
(*) operators are left associative, which
is represented as
infixl in the ghci output
above. A right associative operator is displayed with
:info (^)(^) :: (Num a, Integral b) => a -> b -> a -- Defined in GHC.Real infixr 8 ^
e<interactive>:1:0: Not in scope: `e'
|Don't worry about the error message|
let e = exp 1
This is an application of the exponential
exp, and our first example of
applying a function in Haskell. While languages like Python
require parentheses around the arguments to a function,
Haskell does not.
e defined, we can now
use it in arithmetic expressions. The
(^) exponentiation operator that we
introduced earlier can only raise a number to an integer
power. To use a floating point number as the exponent, we use
(**) exponentiation operator.
(e ** pi) - pi19.99909997918947
|This syntax is ghci-specific|
The syntax for
It is sometimes better to leave at least some parentheses in place, even when Haskell allows us to omit them. Their presence can help future readers (including ourselves) to understand what we intended.
Even more importantly, complex expressions that rely completely on operator precedence are notorious sources of bugs. A compiler and a human can easily end up with different notions of what even a short, parenthesis-free expression is supposed to do.
On most systems, ghci has some amount of command line editing ability. In case you are not familiar with command line editing, 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. On Unix (but not Windows, unfortunately), the tab key completes partially entered identifiers.
|Where to look for more information|
We've barely scratched the surface of command line editing here. Since you can work more effectively if you're more familiar with the capabilities of your command line editing system, you might find it useful to do some further reading.
[1, 2, 3][1,2,3]
|Commas are separators, not terminators|
Some languages permit the last element in a list
to be followed by an optional trailing comma before a closing
bracket, but Haskell doesn't allow this. If you leave in a
trailing comma (e.g.
["foo", "bar", "baz", "quux", "fnord", "xyzzy"]["foo","bar","baz","quux","fnord","xyzzy"]
[True, False, "testing"]<interactive>:1:14: Couldn't match expected type `Bool' against inferred type `[Char]' Expected type: Bool Inferred type: [Char] In the expression: "testing" In the expression: [True, False, "testing"]
.. characters denote
an enumeration. We can only use this
notation for types whose elements we can enumerate. It makes no
sense for text strings, for instance: there is not any sensible,
general way to enumerate
We can omit the end point of an enumeration. If a
type doesn't have a natural “upper bound”, this
will produce values indefinitely. For example, if you type
[1..] at the ghci prompt, you'll have to
interrupt or kill ghci to stop it from printing an infinite
succession of ever-larger numbers. If you are tempted to do
this, type C to
halt the enumeration. We will find later on that infinite lists
are often useful in Haskell.
|Beware enumerating floating point numbers|
Using enumeration notation over floating point numbers can pack more than a few surprises, so if you use it at all, be careful. Floating point behavior is quirky in all programming languages; there is nothing unique to Haskell here.
[3,1,3] ++ [3,7][3,1,3,3,7]
 ++ [False,True] ++ [True][False,True,True]
1 : [2,3][1,2,3]
1 : 
You might be tempted to try writing
to add an element to the end of a list, but ghci will reject
this with an error message, because the first argument of
(:) must be an element, and the second
must be a list.
"This is a string.""This is a string."
As in many languages, we can represent hard-to-see
characters by “escaping” them. Haskell's escape
characters and escaping rules follow the widely used conventions
established by the C language. For example,
'\n' denotes a newline character, and
'\t' is a tab character. For complete
details, see Appendix B, Characters, strings, and escaping rules.
putStrLn "Here's a newline -->\n<-- See?"Here's a newline --> <-- See?
let a = ['l', 'o', 't', 's', ' ', 'o', 'f', ' ', 'w', 'o', 'r', 'k']
a"lots of work"
a == "lots of work"True
"" == True
"foo" ++ "bar""foobar"
While we've talked a little about types already, 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 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.
'c''c' it :: Char
"foo""foo" it :: [Char]
+t does is tell ghci to
print the type of an expression after the expression. That
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. (This
isn't a Haskell language feature; it's specific to ghci
alone.) Let's break down the meaning of the last line of ghci
|The joy of “it”|
When we couple
7 ^ 8040536215597144386832065866109016673800875222251012083746192454448001 it :: Integer
11 % 2911%29 it :: Ratio Integer
Notice two words on the right
hand side of the
:: above. We can read this as a
“Ratio of Integer”. We
might guess that a Ratio must 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, or of the same
non-integral type, ghci complains.
3.14 % 8<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from a 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)
1.2 % 3.4<interactive>:1:0: Ambiguous type variable `t' in the constraints: `Integral t' arising from a use of `%' at <interactive>:1:0-8 `Fractional t' arising from the literal `3.4' at <interactive>:1:6-8 Probable fix: add a type signature that fixes these type variable(s)
Although it is initially useful to have
:set +t giving us type information for
every expression we enter, this is a facility we will quickly
outgrow. After a while, we will often know what type we expect an
expression to have. We can turn off the extra type information
at any time, using the :unset command.
:type 'a''a' :: Char
:type itit :: [Char]
3 + 25
:type itit :: Integer
:type 3 + 23 + 2 :: (Num t) => t
Haskell has several numeric types. For example, a literal
number such as
1 could, depending on the
context in which it appears, be an integer or a floating point
value. When we force ghci to evaluate the expression
+ 2, it has to choose a type so that it can print the
value, and it defaults to Integer. In the second
case, we ask ghci to print the type of the expression without
actually evaluating it, so it does not have to be so specific.
It answers, in effect, “its type is numeric”. We
will see more of this style of type annotation in Chapter 6, Using Typeclasses.
Let's take a small leap ahead, and write a small program
that counts the number of lines in its input. Don't expect to
understand this yet; it's just fun to get our hands dirty. In a
text editor, enter the following code into a file, and save it
-- file: ch01/WC.hs -- lines beginning with "--" are comments. main = interact wordCount where wordCount input = show (length (lines input)) ++ "\n"
Find or create a text file; let's call it
cat quux.txtTeignmouth, England Paris, France Ulm, Germany Auxerre, France Brunswick, Germany Beaumont-en-Auge, France Ryazan, Russia
runghc WC < quux.txt7
We have successfully written a simple program that interacts with the real world! In the chapters that follow, we will successively fill the gaps in our understanding until we can write programs of our own.
 Incidentally, what do these cities have in common?