Exercises for Week 1: Getting Started with Haskell
This document is designed as introduction to Haskell and the
interactive Haskell interpreter GHCi. You are supposed to go through
this document using a computer. It's meant to be pretty simple stuff –
feel free to skip over some exercises.
You are supposed to work through this document in an afternoon. The
most important tasks are to answer questions that look like this:
The questions in the first part come with a suggested answer that you can
see by clicking at the question mark at the left.
Try to answer the questions yourself before looking!
GHCi as a simple calculator
GHCi is an Haskell interpreter, i.e. it is a program that evaluates
You can start GHCi by typing
in a terminal.
We will use
this style for the text that you as user of GHCi have to enter.
When you start GHCi you will see this welcome message:
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Right now, we don't care about the precise meaning of the text in the
message, but focus on the last line with the
symbol indicates that GHCi is ready to receive a command. We will
explain later on what the word
command one can give to GHCi is an Haskell expression, given an Haskell
expression GHCi will evaluate it, and write the result on the screen.
After that, as indicated by the
> symbol, GHCi is ready to take a new command. We can repeat this interaction as many times as we want. Try:
The first of the expressions contains a multiplication-,
addition-, and a subtraction operator. In which order are these
operators applied? Which numbers are mulitplicated, added, and
What will the result be if we take away the parentheses in the first
In which order are the operators applied in the second expression?
We don't always get a value as result when we give GHCi an
can be the case that our expression contains an error...
The first expression contains a syntax error;
there is no right operand of the multiplication
parse error (possibly incorrect indentation or mismatched brackets)
1 `div` 0
*** Exception: divide by zero
*). In the second expression we try to divide by zero.
Recognizing different kinds of errors and knowing their causes will
take some time to learn!
More GHCi commands
We use the :q command to finish a GHCi session.
All GHCi commands except evaluating
an expressions start with a colon
Restart GHCi and try to answer the following questions by inspecting
the welcome message.
Which GHCi commands are there?
Two simple examples
The sell rate for the English pound was 12.7775 SEK on the 20th of October
2008. How many pounds did one get for 1000 SEK that day?
In some countries people use the Fahrenheit temperature scale. 0°C
(Celsius) corresponds to 32°F (Fahrenheit), and an increase of 5°C
corresponds to an increase of 9°F. How many Fahrenheit degrees is 28°C?
A programmable pocket calculator
We have seen how we can use GHCi to do simple calculations. But this
is just the beginning. To go further we need to define our own functions.
As a first example we look at the currency conversion
problem described above. If we need to repeatedly convert pounds to SEK
we can define a function that does
this for us. Defining a function consists of a number of steps.
Before we can use the definition we have to give it to GHCi.
Although it is possible to do this directly in GHCi, it is more useful to
learn how to do this in a seperate file, since this is what we have to do for larger programs.
We can now use the definition: Try:
Use an editor (for example Emacs or nedit) to write the function
definition in a file. Do this, start Emacs with the command
emacs ex1.hs & in a terminal, and
write the definition above. Save this to a file with name ex1.hs
Give GHCi a command to load the file
Compiling Main ( ex1.hs, interpreted )
Ok, modules loaded: Main.
Define a function that converts temperatures in °C to °F.
Add this function to ex1.hs
. Load the file and test your
We will now introduce a new kind of error.
What happens if one writes
(note the spelling error)?
What happens if one writes:
Comparison and more complex functions
Up till now we have defined functions by equations of the form:
name(parameter) = an expressions containing the parameter, numbers and arithmetic operations.
It is not always this easy, consider the following example:
A shop sells potatoes for 3.50 SEK/kg. To stimulates
large sales, the shop offers a reduced price of 3 SEK/kg for the
quantity exceeding 10 kg.
Let's call this function
We want to define the function that calculates the price.
price and the parameter
So, we have:
v is at most 10, then the price is
v is more than 10, the price is
(check this!) which is equal to
price(v) = 3.5*v, if
price(v) = 5+3*v, if
How does one write this in Haskell? First, notice that it is possible to
The result of such a comparison is either
3 < 6
3.5 <= 3
pounds 4000 > 3*100
False. Notice, that smaller than or equal to is written
Now, we can write the definition of price as follows:
price :: Double -> Double
| v <= 10 = 3.5*v
| v > 10 = 5+3*v
The Boolean expressions between
are called guards. When this function is
applied to a particular argument, GHCi checks the guards from
top to bottom until it finds one that evaluates to
after that the right-hand side of the expression is used to calculate
If all guards evaluate to
False GHCi gives an error message.
Load this function into GHCi, and test the function price on different
Change the last of the definitions to:
|v > 11 = 5+3*v
What is the result of applying the function to 9.5, 10.5
We can use the keyword
Change the function to:
|v <= 11 = 3.5*v
|v > 10 = 5+3*v
What is the now result of applying the function to 9.5, 10.5
otherwise as a guard that is always
true. So, if
otherwise is used as the last guard, the
expression at the right-hand side will be used if none of the other
guards evaluates to
So, we can write:
price :: Double -> Double
|v <= 10 = 3.5*v
|otherwise = 5+3*v
The sale of potatoes has been so successful that the shop now can offer a
price of 2.50 SEK/kilo for quantities exceeding 20kg (with the same prices for
other amounts). Change the function to to calculate the correct price.
otherwise a Haskell keyword? What does Hoogle say?
When a function is applied to a simple argument (like 5) we don't need parentheses. But if the argument is composed (like 4 +
8) parentheses are needed.
Try to evaluate the last expression without parentheses.
Can you explain the result?
Functions with more than one argument
Functions can have more than one argument. As an example we define a
function that defines the average of two numbers:
Observe that when a function has multiple arguments the parameters are
written after each other separated by spaces.
The same holds when the function is applied to parameters.
average 5 8
Define a function
that gives the average of three numbers. Load in the function in GHCi
and test it.
Some functions are very frequently used and therefore pre-defined in a module (file) called the Prelude, which is
loaded automatically every time GHCi is started. An overview of the
functions defined can be found in e.g.,
A Tour of the Haskell Prelude.
To be able to program efficiently in Haskell it is necessary to know
which functions are available in the Prelude. In the coming weeks you
will become more familiar with them.
Operators and functions with two arguments
Operators like *,-,+ are written infix,
which means that the operator should be in between
its arguments. Functions are usually written prefix, meaning that they are
written before their arguments.
However, one can use a function infix by writing it
`. An operator can be used prefix by writing it in between parentheses.
5 `average` 4
4 `max` (5 `max` 2)
(+) 3 4
The prelude provide the function
div for integer division.
div 17 5
div 34 8
div 5 9
4 `div` 2
mod gives the remainder for integer division:
17 `mod` 5
34 `mod` 8
5 `mod` 9
mod 4 2
5 `mod` 0
Is 107139224 divisible by 11731?
Define a function
that given a year gives the number of days in that year. Used the
simplified rule that year numbers divisible by four are leap years
(years with 366 days).
You will have to use relational operator
which evaluates to
if its arguments are equal.
A bigger example
Consider the following game:
Think of an whole number greater than one. If its even,
divide it by two, otherwise multiply it by three and add one. Stop if
the resulting number is one, otherwise repeat the procedure.
As example, we start width 10.
- 10 is even, so the next number is: 10/2 = 5
- 5 is odd so the next number is: 3*5+1=16
- 16 is even, so the next number is: 16/2 = 8
- 8 is even, so the next number is: 8/2 = 4
- 4 is even, so the next number is: 4/2 = 2
- 2 is even, so the next number is: 1.
If we start with 7 we get: (Check this!)
7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1.
We are interested in the question: Given a number n, how many
numbers are there in the sequence?
For n=10, we get 7 numbers (10, 5, 16, 8, 4, 2, 1).
For n=7 we get 17 numbers (See above).
Note that we include both the number n we start with and the final
How can GHCi help us to answer the question? We start with defining
next that given a number computes the next number
in the sequence.
Define the function
What is the length of the sequence for n = 6?
Guided by the previous exercise we observe that the function steps
We want to define
that takes a number n
and calculates the length of the generated sequence. What is
steps :: Int -> Int
| n == 1 = 1
| otherwise = steps(next n)+1
We call this a recursive definition.
(You should have met this concept before - otherwise ask for a refund on your undergraduate education!)
Write the definition in your file. Load it in to GHCi, and calculate
n for several different values of n.
It all seems to work without any problem. But at the same time one can
Finally, we define the function
Can you be sure that eventually you will reach the number 1 no matter
what number you start with?
numbers that calculates the
actual list of numbers generated in the game:
numbers :: Int -> [Int]
| n==1 = 
| otherwise = n : numbers(next n)
Load the function into GHCi and try:
Study the function definition: When n=1 the result is the list
[10, 5, 16, 8, 4, 2, 1]
[17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
. Otherwise we use the operator
named cons, which constructs a list from an element and a list by placing
the element at the front of the list.
The result of
numbers n is
followed by the list
Now we have defined the function numbers we don't need to
define steps anymore because there is a function length
in the prelude that calculates the length of a list. Try:
length (numbers 10)