1 / 94

Introduction to Programming in Haskell

- Koen Lindström Claessen

Programming

- Exciting subject at the heart of computing
- Never programmed?
- Learn to make the computer obey you!
- Programmed before?
- Lucky you! Your knowledge will help a lot...
- ...as you learn a completely new way to program
- Everyone will learn a great deal from this course!

Goal of the Course

- Start from the basics, after Datorintroduktion
- Learn to write small-to-medium sized programs in

Haskell - Introduce basic concepts of computer science

The Flow

Do not break the flow!

You prepare in advance

I explain in lecture

Tuesdays,Fridays

You learn with exercises

You put to practice with lab assignments

Mondays/Tuesdays

Submit end of each week

Exercise Sessions

- Mondays or Tuesdays
- Depending on what group you are in
- Come prepared
- Work on exercises together
- Discuss and get help from tutor
- Personal help
- Make sure you understand this weeks things

before you leave

Lab Assignments

- Work in pairs
- (Almost) no exceptions!
- Lab supervision
- Book a time in advance
- One time at a time!
- Start working on lab when you have understood the

matter - Submit end of each week
- Feedback
- Return The tutor has something to tell you fix

and submit again - OK You are done

even this week!

Getting Help

- Weekly group sessions
- personal help to understand material
- Lab supervision
- specific questions about programming assignment

at hand - Discussion forum
- general questions, worries, discussions

Assessment

- Written exam (3 credits)
- Consists of small programming problems to solve

on paper - You need Haskell in your fingers
- Course work (2 credits)
- Complete all labs successfully

A Risk

- 7 weeks is a short time to learn programming
- So the course is fast paced
- Each week we learn a lot
- Catching up again is hard
- So do keep up!
- Read the text book each week
- Make sure you can solve the problems
- Go to the weekly exercise sessions
- From the beginning

Course Homepage

- The course homepage will have ALL up-to-date

information relevant for the course - Schedule
- Lab assignments
- Exercises
- Last-minute changes
- (etc.)

Or Google for chalmers introduction functional

programming

http//www.cs.chalmers.se/Cs/Grundutb/Kurser/funht

/

Software

Software Programs Data

Data

- Data is any kind of storable information.

Examples

- Numbers
- Letters
- Email messages
- Songs on a CD

- Maps
- Video clips
- Mouse clicks
- Programs

Programs

Programs compute new data from old

data. Example Baldurs Gate computes a sequence

of screen images and sounds from a sequence of

mouse clicks.

Building Software Systems

A large system may contain many millions of lines

of code. Software systems are among the most

complex artefacts ever made. Systems are built

by combining existing components as far as

possible.

Bonnier buys Quicktime Video from Apple.

Volvo buys engines from Mitsubishi.

Programming Languages

Programs are written in programming

languages. There are hundreds of different

programming languages, each with their strengths

and weaknesses. A large system will often

contain components in many different languages.

Programming Languages

which language should we teach?

Scheme

C

Lisp

BASIC

C

Haskell

Java

C

ML

Python

JavaScript

csh

Curry

Perl

OCaML

bash

Erlang

Ruby

Prolog

Lustre

Mercury

PostScript

VHDL

Esterel

SQL

Verilog

Programming Language Features

dynamically typed

pure functions

higher-order functions

statically typed

type inference

real-time

immutable datastructures

polymorphism

overloading

concurrency

high performance

distribution

parameterized types

lazy

virtual machine

Java

reflection

type classes

object oriented

compiler

interpreter

meta-programming

Haskell

unification

C

backtracking

Teaching Programming

- Give you a broad basis
- Easy to learn more programming languages
- Easy to adapt to new programming languages
- Haskell is defining state-of-the-art in

programming language development - Appreciate differences between languages
- Become a better programmer!

Industrial Uses of Functional Languages

Intel (microprocessor verification) Hewlett

Packard (telecom event correlation) Ericsson

(telecommunications) Carlstedt Research

Technology (air-crew scheduling)

Hafnium (Y2K tool) Shop.com (e-commerce) Motorola

(test generation) Thompson (radar

tracking) Microsoft (SDV) Jasper (hardware

verification)

Why Haskell?

- Haskell is a very high-level language (many

details taken care of automatically). - Haskell is expressive and concise (can achieve a

lot with a little effort). - Haskell is good at handling complex data and

combining components. - Haskell is not a high-performance language

(prioritise programmer-time over computer-time).

A Haskell Demo

- Start the GHCi Haskell interpreter

- gt ghci
- ___ ___ _
- / _ \ /\ /\/ __(_)
- / /_\// /_/ / / GHC Interactive,

version 6.6.1, for Haskell 98. - / /_\\/ __ / /___ http//www.haskell.org/

ghc/ - \____/\/ /_/\____/_ Type ? for help.
- Loading package base ... linking ... done.
- Preludegt

The prompt. GHCi is ready for input.

GHCi as a Calculator

Type in expressions, and ghci calculates and

prints their value.

Preludegt 22 4 Preludegt 2-2 0 Preludegt

23 6 Preludegt 2/3 0.666666666666667

Multiplication and division look a bit unfamiliar

we cannot omit multiplication, or type

horizontal lines.

X

2

3

Binding and Brackets

Preludegt 223 8 Preludegt (22)3 12 Prelude

gt (12)/(34) 0.428571428571429

Multiplication and division bind more tightly

than addition and subtraction so this means

26, not 43.

We use brackets to change the binding (just as in

mathematics), so this is 43.

This is how we write 12 34

Quiz

- What is the value of this expression?
- Preludegt 12/34

Quiz

- What is the value of this expression?
- Preludegt 12/34
- 5.66666666666667

Example Currency Conversion

- Suppose we want to buy a game costing 53 from a

foreign web site.

Preludegt 539.16642 485.82026

Exchange rate 1 9.16642 SEK

Price in SEK

Boring to type 9.16642 every time we convert a

price!

Naming a Value

- We give a name to a value by making a definition.
- Definitions are put in a file, using a text

editor such as emacs. - gt emacs Examples.hs

Do this in a separate window, so you can edit and

run hugs simultaneously.

Haskell files end in .hs

The UNIX prompt, not the ghci one!

Creating the Definition

Give the name euroRate to the value 9.16642

variable

Using the Definition

Load the file Examples.hs into ghci make the

definition available.

The prompt changes we have now loaded a program.

Preludegt l Examples Maingt euroRate 9.16642 Maingt

53euroRate 485.82026 Maingt

We are free to make use of the definition.

Functional Programming is based on Functions

- A function is a way of computing a result from

its arguments - A functional program computes its output as a

function of its input - E.g. Series of screen images from a series of

mouse clicks - E.g. Price in SEK from price in euros

A Function to convert Euros to SEK

A definition placed in the file Examples.hs

A comment to help us understand the program

-- convert euros to SEK sek x xeuroRate

Function name the name we are defining.

Expression to compute the result

Name for the argument

Using the Function

Reload the file to make the new definition

available.

Maingt r Maingt sek 53 485.82026

Call the function Notation no brackets! C.f. sin

0.5, log 2, not f(x).

sek x xeuroRate

x 53 While we evaluate the right hand side

53euroRate

Binding and Brackets again

Different! This is (sek 50) 3. Functions bind

most tightly of all.

Maingt sek 53 485.82026 Maingt sek 50

3 461.321 Maingt sek (503) 485.82026 Maingt

Use brackets to recover sek 53.

No stranger than writing sin ? and sin (? ?)

Converting Back Again

-- convert SEK to euros euro x x/euroRate

Maingt r Maingt euro 485.82026 53.0 Maingt euro

(sek 49) 49.0 Maingt sek (euro 217) 217.0

Testing the program trying it out to see if does

the right thing.

Automating Testing

- Why compare the result myself, when I have a

computer?

The operator tests whether two values are equal

Maingt 2 2 True Maingt 2 3 False Maingt euro

(sek 49) 49 True

Yes they are

No they arent

Note two equal signs are an operator. One equal

sign makes a definition.

Let the computer check the result.

Defining the Property

- Define a function to perform the test for us

prop_EuroSek x euro (sek x) x

Maingt prop_EuroSek 53 True Maingt prop_EuroSek

49 True

Performs the same tests as before but now we

need only remember the function name!

Writing Properties in Files

- Functions with names beginning prop_ are

properties they should always return True - Writing properties in files
- Tells us how functions should behave
- Tells us what has been tested
- Lets us repeat tests after changing a definition
- Properties help us get programs right!

Automatic Testing

- Testing account for more than half the cost of a

software project - We will use a tool for automatic testing

import Test.QuickCheck

Capital letters must appear exactly as they do

here.

Add first in the file of definitions makes

QuickCheck available.

Running Tests

Runs 100 randomly chosen tests

Maingt quickCheck prop_EuroSek Falsifiable, after

10 tests 3.75 Maingt sek 3.75 34.374075 Maingt

euro 34.374075 3.75

Its not true!

The value for which the test fails.

Looks OK

The Problem

- There is a very tiny difference between the

initial and final values - Calculations are only performed to about 15

significant figures - The property is wrong!

Maingt euro (sek 3.75) - 3.75 4.44089209850063e-016

e means 10

-16

Fixing the Problem

- The result should be nearly the same
- The difference should be small say lt0.000001

Maingt 2lt3 True Maingt 3lt2 False

We can use lt to see whether one number is less

than another

Defining Nearly Equal

- We can define new operators with names made up of

symbols

x y x-y lt 0.000001

With arguments x and y

Which returns True if the difference between x

and y is less than 0.000001

Define a new operator

Testing

Maingt 3 3.0000001 True Maingt 34 True

OK

Whats wrong?

x y x-y lt 0.000001

Fixing the Definition

- A useful function

Maingt abs 3 3 Maingt abs (-3) 3

Absolute value

x y abs (x-y) lt 0.000001

Maingt 3 4 False

Fixing the Property

prop_EuroSek x euro (sek x) x

Maingt prop_EuroSek 3 True Maingt prop_EuroSek

56 True Maingt prop_EuroSek 2 True

Name the Price

- Lets define a name for the price of the game we

want

price 53

Maingt sek price ERROR - Type error in

application Expression sek price

Term price Type

Integer Does not match Double

Every Value has a Type

- The i command prints information about a name

Integer (whole number) is the type of price

Maingt i price price Integer Maingt i

euroRate euroRate Double

Double is the type of real numbers Funny name,

but refers to double the precision that computers

originally used

More Types

The type of truth values, named after the

logician Boole

Maingt i True True Bool -- data

constructor Maingt i False False Bool --

data constructor Maingt i sek sek Double -gt

Double Maingt i prop_EuroSek prop_EuroSek

Double -gt Bool

The type of a function

Type of the result

Type of the result

Type of the argument

Types Matter

- Types determine how computations are performed

Specify which type to use

Maingt 123456789123456789 Double 1.524157875019

05e016 Maingt 123456789123456789

Integer 15241578750190521

Correct to 15 figures

The exact result 17 figures (but must be an

integer)

Hugs must know the type of each expression before

computing it.

Type Checking

- Infers (works out) the type of every expression
- Checks that all types match before running the

program

Our Example

Maingt i price price Integer Maingt i sek sek

Double -gt Double Maingt sek price ERROR - Type

error in application Expression sek

price Term price Type

Integer Does not match Double

Why did it work before?

Certainly works to say 53 What is the type of 53?

Maingt sek 53 485.82026 Maingt 53

Integer 53 Maingt 53 Double 53.0 Maingt price

Integer 53 Maingt price Double ERROR - Type

error in type annotation Term

price Type Integer Does not

match Double

53 can be used with several types it is

overloaded

Giving it a name fixes the type

Fixing the Problem

- Definitions can be given a type signature which

specifies their type

price Double price 53

Maingt i price price Double Maingt sek

price 485.82026

Always Specify Type Signatures!

- They help the reader (and you) understand the

program - The type checker can find your errors more

easily, by checking that definitions have the

types you say - Type error messages will be easier to understand
- Sometimes they are necessary (as for price)

Example with Type Signatures

euroRate Double euroRate 9.16642 sek, euro

Double -gt Double sek x xeuroRate euro x

x/euroRate prop_EuroSek Double -gt

Bool prop_EuroSek x euro (sek x) x

What is the type of 53?

i only works for names

Maingt i 53 Unknown reference 53' Maingt t sek

53 sek 53 Double Maingt t 53 53 Num a gt

a Maingt i infixl 7 () Num a gt a -gt a

-gt a -- class member

But t gives the type (only) of any expression

Then 53 can have type a

If a is a numeric type

If a is a numeric type

Then can have type a-gta-gta

What is Num exactly?

Maingt i Num -- type class ... class (Eq a,

Show a) gt Num a where () a -gt a -gt a (-)

a -gt a -gt a () a -gt a -gt a ... --

instances instance Num Int instance Num

Integer instance Num Float instance Num

Double instance Integral a gt Num (Ratio a)

A class of types

With these operations

Types which belong to this class

Examples

Maingt 2 3.5 5.5 Maingt True 3 ERROR - Cannot

infer instance Instance Num Bool

Expression True 3

2, , and 3.5 can all work on Double

Sure enough, Bool is not in the Num class

A Tricky One!

Maingt sek (-10) -91.6642 Maingt sek -10 ERROR -

Cannot infer instance Instance Num

(Double -gt Double) Expression sek - 10

Whats going on?

Operators Again

Maingt i infixl 6 () Num a gt a -gt a -gt a

-- class member Maingt i infixl 7 ()

Num a gt a -gt a -gt a -- class member

The binding power (or precedence) of an

operator binds tighter than because 7 is

greater than 6

Giving a Precedence

Maingt 1/2000000 0 ERROR - Cannot infer

instance Instance Fractional Bool

Expression 1 / 2000000 0

Wrongly interpreted as 1 / (2000000

0) Instead of (1/2000000) 0

Giving a Precedence

- should bind the same way as

Maingt i infix 4 () Eq a gt a -gt a -gt

Bool -- class member

infix 4 x y abs (x-y) lt 0.000001

Maingt 1/2000000 0 True

Summary

- Think about the properties of your program
- ... and write them down
- It helps you understanding
- the problem you are solving
- the program you are writing
- It helps others understanding what you did
- co-workers
- customers
- you in 1 year from now

Cases and Recursion

Example The squaring function

- Example a function to compute

-- sq x returns the square of x sq Integer -gt

Integer sq x x x

Evaluating Functions

- To evaluate sq 5
- Use the definitionsubstitute 5 for x throughout
- sq 5 5 5
- Continue evaluating expressions
- sq 5 25
- Just like working out mathematics on paper

sq x x x

Example Absolute Value

- Find the absolute value of a number

-- absolute x returns the absolute value of

x absolute Integer -gt Integer absolute x

undefined

Example Absolute Value

- Find the absolute value of a number
- Two cases!
- If x is positive, result is x
- If x is negative, result is -x

Programs must often choose between alternatives

-- absolute x returns the absolute value of

x absolute Integer -gt Integer absolute x x gt

0 undefined absolute x x lt 0 undefined

Think of the cases! These are guards

Example Absolute Value

- Find the absolute value of a number
- Two cases!
- If x is positive, result is x
- If x is negative, result is -x

-- absolute x returns the absolute value of

x absolute Integer -gt Integer absolute x x gt

0 x absolute x x lt 0 -x

Fill in the result in each case

Example Absolute Value

- Find the absolute value of a number
- Correct the code

-- absolute x returns the absolute value of

x absolute Integer -gt Integer absolute x x

gt 0 x absolute x x lt 0 -x

gt is greater than or equal,

Evaluating Guards

- Evaluate absolute (-5)
- We have two equations to use!
- Substitute
- absolute (-5) -5 gt 0 -5
- absolute (-5) -5 lt 0 -(-5)

absolute x x gt 0 x absolute x x lt 0 -x

Evaluating Guards

- Evaluate absolute (-5)
- We have two equations to use!
- Evaluate the guards
- absolute (-5) False -5
- absolute (-5) True -(-5)

Discard this equation

Keep this one

absolute x x gt 0 x absolute x x lt 0 -x

Evaluating Guards

- Evaluate absolute (-5)
- We have two equations to use!
- Erase the True guard
- absolute (-5) -(-5)

absolute x x gt 0 x absolute x x lt 0 -x

Evaluating Guards

- Evaluate absolute (-5)
- We have two equations to use!
- Compute the result
- absolute (-5) 5

absolute x x gt 0 x absolute x x lt 0 -x

Notation

- We can abbreviate repeated left hand sides
- Haskell also has if then else

absolute x x gt 0 x absolute x x lt 0 -x

absolute x x gt 0 x x lt 0 -x

absolute x if x gt 0 then x else -x

Example Computing Powers

- Compute (without using built-in xn)

Example Computing Powers

- Compute (without using built-in xn)
- Name the function

power

Example Computing Powers

- Compute (without using built-in xn)
- Name the inputs

power x n undefined

Example Computing Powers

- Compute (without using built-in xn)
- Write a comment

-- power x n returns x to the power n power x n

undefined

Example Computing Powers

- Compute (without using built-in xn)
- Write a type signature

-- power x n returns x to the power n power

Integer -gt Integer -gt Integer power x n

undefined

How to Compute power?

- We cannot write
- power x n x x

n times

A Table of Powers

- Each row is x the previous one
- Define power x n to compute the nth row

n

power x n

0

1

1

x

2

xx

3

xxx

A Definition?

power x n x power x (n-1)

- Testing
- Maingt power 2 2
- ERROR - stack overflow

Why?

A Definition?

- Testing
- Maingt power 2 2
- Program error pattern match failure power 2 0

power x n n gt 0 x power x (n-1)

A Definition?

First row of the table

- Testing
- Maingt power 2 2
- 4

power x 0 1 power x n n gt 0 x power x

(n-1)

The BASE CASE

Recursion

- First example of a recursive function
- Defined in terms of itself!
- Why does it work? Calculate
- power 2 2 2 power 2 1
- power 2 1 2 power 2 0
- power 2 0 1

power x 0 1 power x n n gt 0 x power x

(n-1)

Recursion

- First example of a recursive function
- Defined in terms of itself!
- Why does it work? Calculate
- power 2 2 2 power 2 1
- power 2 1 2 1
- power 2 0 1

power x 0 1 power x n n gt 0 x power x

(n-1)

Recursion

- First example of a recursive function
- Defined in terms of itself!
- Why does it work? Calculate
- power 2 2 2 2
- power 2 1 2 1
- power 2 0 1

power x 0 1 power x n n gt 0 x power x

(n-1)

No circularity!

Recursion

- First example of a recursive function
- Defined in terms of itself!
- Why does it work? Calculate
- power 2 2 2 power 2 1
- power 2 1 2 power 2 0
- power 2 0 1

power x 0 1 power x n n gt 0 x power x

(n-1)

The STACK

Recursion

- Reduce a problem (e.g. power x n) to a smaller

problem of the same kind - So that we eventually reach a smallest base

case - Solve base case separately
- Build up solutions from smaller solutions

Powerful problem solving strategy in any

programming language!

Counting the regions

- n lines. How many regions?

remove one line ...

problem is easier!

when do we stop?

The Solution

- Always pick the base case as simple as possible!

regions Integer -gt Integer regions 0

1 regions n n gt 0 regions (n-1) n

Course Text Book

uses Hugs instead of GHCi

The Craft of Functional Programming (second

edition), by Simon Thompson. Available at

Cremona. An excellent book which goes well beyond

this course, so will be useful long after the

course is over. Read Chapter 1 to 4 before the

laboratory sessions on Wednesday, Thursday and

Friday.

Course Web Pages

Updated almost daily!

URL http//www.cs.chalmers.se/Cs/Grundutb/Kurser

/funht/

- These slides
- Schedule
- Practical information
- Assignments
- Discussion board