introduction to programming in haskell

94
Introduction to Programming in Haskell Koen Lindström Claessen

Upload: aleta

Post on 19-Mar-2016

76 views

Category:

Documents


1 download

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Introduction to Programming in Haskell

Introduction to Programming in Haskell

Koen Lindström Claessen

Page 2: Introduction to Programming in Haskell

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!

Page 3: Introduction to Programming in Haskell

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

Page 4: Introduction to Programming in Haskell

The Flow

You preparein advance

I explainin lecture

You learnwith exercises

You put to practicewith lab assignments

Tuesdays,Fridays

Mondays/Tuesdays

Submit end of each week

Do not break the flow!

Page 5: Introduction to Programming in Haskell

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 week’s

things before you leave

Page 6: Introduction to Programming in Haskell

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!

Page 7: Introduction to Programming in Haskell

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

Page 8: Introduction to Programming in Haskell

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

Page 9: Introduction to Programming in Haskell

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

Page 10: Introduction to Programming in Haskell

Course Homepage

• The course homepage will have ALL up-to-date information relevant for the course– Schedule– Lab assignments– Exercises– Last-minute changes– (etc.)

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

Or Google for ”chalmers

introduction functional

programming”

Page 11: Introduction to Programming in Haskell

Software

Software = Programs + Data

Page 12: Introduction to Programming in Haskell

DataData is any kind of storable information. Examples:

•Numbers

•Letters

•Email messages

•Songs on a CD

•Maps

•Video clips

•Mouse clicks

•Programs

Page 13: Introduction to Programming in Haskell

Programs

Programs compute new data from old data.

Example: Baldur’s Gate computes a sequence of screen images and sounds from a sequence of mouse clicks.

Page 14: Introduction to Programming in Haskell

Building Software SystemsA 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.

Volvo buys engines from Mitsubishi.

Bonnier buys Quicktime Video from Apple.

Page 15: Introduction to Programming in Haskell

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.

Page 16: Introduction to Programming in Haskell

Programming LanguagesC

Haskell Java

ML

O’CaML

C++

C#

Prolog

Perl

Python

Ruby

PostScript

SQL

Erlang

PDF

bash

JavaScript

Lisp Scheme BASIC

csh

VHDL

Verilog

Lustre

Esterel

Mercury

Curry

which language should we teach?

Page 17: Introduction to Programming in Haskell

Programming Language Features

polymorphism

higher-order functionsstatically

typed

parameterized types

overloading

type classes object

oriented

reflection

meta-programming

compiler

virtual machine

interpreter

pure functions

lazyhigh

performance

type inference

dynamically typed

immutable datastructures

concurrency

distribution

real-time

Haskell unificationbacktracking

Java

C

Page 18: Introduction to Programming in Haskell

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!

Page 19: Introduction to Programming in Haskell

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)

Page 20: Introduction to Programming in Haskell

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).

Page 21: Introduction to Programming in Haskell

A Haskell Demo

• Start the GHCi Haskell interpreter:> ghci

___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.1, for Haskell 98./ /_\\/ __ / /___| | http://www.haskell.org/ghc/\____/\/ /_/\____/|_| Type :? for help.

Loading package base ... linking ... done.Prelude>

The prompt. GHCi is ready for input.

Page 22: Introduction to Programming in Haskell

GHCi as a CalculatorPrelude> 2+24Prelude> 2-20Prelude> 2*36Prelude> 2/30.666666666666667

Type in expressions, and ghci calculates and prints

their value.

Multiplication and division look a bit unfamiliar – we cannot omit multiplication,

or type horizontal lines.

23 X

Page 23: Introduction to Programming in Haskell

Binding and BracketsPrelude> 2+2*38

Prelude> (2+2)*312

Prelude> (1+2)/(3+4)0.428571428571429

Multiplication and division ”bind more tightly” than

addition and subtraction – so this means 2+6, not 4*3.

We use brackets to change the binding (just as in

mathematics), so this is 4*3.

This is how we write1+23+4

Page 24: Introduction to Programming in Haskell

Quiz

• What is the value of this expression?Prelude> 1+2/3+4

Page 25: Introduction to Programming in Haskell

Quiz

• What is the value of this expression?Prelude> 1+2/3+45.66666666666667

Page 26: Introduction to Programming in Haskell

Example: Currency Conversion

• Suppose we want to buy a game costing €53 from a foreign web site.

Prelude> 53*9.16642485.82026

Exchange rate: €1 = 9.16642 SEK

Price in SEKBoring to type 9.16642 every time we convert a price!

Page 27: Introduction to Programming in Haskell

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.> emacs Examples.hs

The UNIX prompt, not the ghci one!

Do this in a separate window, so you can

edit and run hugs simultaneously.

Haskell files end in .hs

Page 28: Introduction to Programming in Haskell

Creating the Definition

Give the name euroRate to the value 9.16642

variable

Page 29: Introduction to Programming in Haskell

Using the Definition

Prelude> :l ExamplesMain> euroRate9.16642Main> 53*euroRate485.82026Main>

Load the file Examples.hs into ghci – make the

definition available.

The prompt changes – we

have now loaded a program.

We are free to make use of the definition.

Page 30: Introduction to Programming in Haskell

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

Page 31: Introduction to Programming in Haskell

A Function to convert Euros to SEK

-- convert euros to SEKsek x = x*euroRate

Function name – the name we are defining.

Name for the argument

Expression to compute the

result

A definition – placed in the

file Examples.hs

A comment – to help us understand the program

Page 32: Introduction to Programming in Haskell

Using the Function

Main> :rMain> sek 53485.82026

Reload the file to make the new definition available.

Call the functionNotation: no brackets!

C.f. sin 0.5, log 2, not f(x).

sek x = x*euroRate

x = 53While we evaluate the right hand side

53*euroRate

Page 33: Introduction to Programming in Haskell

Binding and Brackets again

Main> sek 53485.82026Main> sek 50 + 3461.321Main> sek (50+3)485.82026Main>

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

tightly of all.

Use brackets to recover sek 53.

No stranger than writing

sin and sin ( + )

Page 34: Introduction to Programming in Haskell

Converting Back Again-- convert SEK to euroseuro x = x/euroRate

Main> :rMain> euro 485.8202653.0Main> euro (sek 49)49.0Main> sek (euro 217)217.0

Testing the program: trying it out to see if does the right thing.

Page 35: Introduction to Programming in Haskell

Automating Testing

• Why compare the result myself, when I have a computer?

Main> 2 == 2TrueMain> 2 == 3False Main> euro (sek 49) == 49True

The operator == tests whether two values are equal

Yes they are

No they aren’t

Let the computer check the result.

Note: two equal signs are an operator.

One equal sign makes a definition.

Page 36: Introduction to Programming in Haskell

Defining the Property

• Define a function to perform the test for us

prop_EuroSek x = euro (sek x) == x

Main> prop_EuroSek 53TrueMain> prop_EuroSek 49True

Performs the same tests as before – but now we need only remember the function name!

Page 37: Introduction to Programming in Haskell

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!

Page 38: Introduction to Programming in Haskell

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

Add first in the file of definitions – makes

QuickCheck available.

Capital letters must appear exactly as they

do here.

Page 39: Introduction to Programming in Haskell

Running TestsMain> quickCheck prop_EuroSekFalsifiable, after 10 tests:3.75

Main> sek 3.7534.374075Main> euro 34.3740753.75

Runs 100 randomly

chosen testsIt’s not true!

The value for which the test fails.

Looks OK

Page 40: Introduction to Programming in Haskell

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!

Main> euro (sek 3.75) - 3.754.44089209850063e-016 e means

£ 10-16

Page 41: Introduction to Programming in Haskell

Fixing the Problem

• The result should be nearly the same• The difference should be small – say

<0.000001Main> 2<3TrueMain> 3<2False

We can use < to see whether one number is less than another

Page 42: Introduction to Programming in Haskell

Defining ”Nearly Equal”

• We can define new operators with names made up of symbols

x ~== y = x-y < 0.000001

Define a new operator ~==

With arguments x

and y

Which returns True if the difference

between x and y is less than 0.000001

Page 43: Introduction to Programming in Haskell

Testing ~==

Main> 3 ~== 3.0000001TrueMain> 3~==4True

OK

What’s wrong?

x ~== y = x-y < 0.000001

Page 44: Introduction to Programming in Haskell

Fixing the Definition

• A useful functionMain> abs 33Main> abs (-3)3

Absolute value

x ~== y = abs (x-y) < 0.000001

Main> 3 ~== 4False

Page 45: Introduction to Programming in Haskell

Fixing the Property

prop_EuroSek x = euro (sek x) ~== x

Main> prop_EuroSek 3True Main> prop_EuroSek 56TrueMain> prop_EuroSek 2True

Page 46: Introduction to Programming in Haskell

Name the Price

• Let’s define a name for the price of the game we want

price = 53

Main> sek priceERROR - Type error in application*** Expression : sek price*** Term : price*** Type : Integer*** Does not match : Double

Page 47: Introduction to Programming in Haskell

Every Value has a Type

• The :i command prints information about a name

Main> :i priceprice :: Integer

Main> :i euroRateeuroRate :: Double

Integer (whole number) is the type of price

Double is the type of real numbers

Funny name, but refers to double the precision that computers originally used

Page 48: Introduction to Programming in Haskell

More Types

Main> :i TrueTrue :: Bool -- data constructor

Main> :i FalseFalse :: Bool -- data constructor

Main> :i seksek :: Double -> Double

Main> :i prop_EuroSekprop_EuroSek :: Double -> Bool

The type of truth values, named after the logician Boole

The type of a function

Type of the argument

Type of the resultType of the result

Page 49: Introduction to Programming in Haskell

Types Matter

• Types determine how computations are performed

Main> 123456789*123456789 :: Double1.52415787501905e+016

Main> 123456789*123456789 :: Integer15241578750190521

Correct to 15 figures

Specify which type to use

The exact result – 17 figures(but must be an integer)

Hugs must know the type of each expression before computing it.

Page 50: Introduction to Programming in Haskell

Type Checking

• Infers (works out) the type of every expression

• Checks that all types match – before running the program

Page 51: Introduction to Programming in Haskell

Our ExampleMain> :i priceprice :: Integer

Main> :i seksek :: Double -> Double

Main> sek priceERROR - Type error in application*** Expression : sek price*** Term : price*** Type : Integer*** Does not match : Double

Page 52: Introduction to Programming in Haskell

Why did it work before?Main> sek 53485.82026Main> 53 :: Integer53Main> 53 :: Double53.0Main> price :: Integer53Main> price :: DoubleERROR - Type error in type annotation*** Term : price*** Type : Integer*** Does not match : Double

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

53 can be used with several types – it is overloaded

Giving it a name fixes the type

Page 53: Introduction to Programming in Haskell

Fixing the Problem

• Definitions can be given a type signature which specifies their type

price :: Doubleprice = 53

Main> :i priceprice :: Double

Main> sek price485.82026

Page 54: Introduction to Programming in Haskell

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)

Page 55: Introduction to Programming in Haskell

Example with Type Signatures

euroRate :: DoubleeuroRate = 9.16642

sek, euro :: Double -> Doublesek x = x*euroRateeuro x = x/euroRate

prop_EuroSek :: Double -> Boolprop_EuroSek x = euro (sek x) ~== x

Page 56: Introduction to Programming in Haskell

What is the type of 53?Main> :i 53Unknown reference `53'Main> :t sek 53sek 53 :: Double Main> :t 5353 :: Num a => a

Main> :i *infixl 7 *(*) :: Num a => a -> a -> a -- class member

:i only works for names

But :t gives the type (only) of any expression

If a is a numeric type Then 53 can have type aIf a is a numeric type

Then * can have type a->a->a

Page 57: Introduction to Programming in Haskell

What is Num exactly?Main> :i Num-- type class...class (Eq a, Show a) => Num a where (+) :: a -> a -> a (-) :: a -> a -> a (*) :: a -> a -> a...-- instances:instance Num Intinstance Num Integerinstance Num Floatinstance Num Doubleinstance Integral a => Num (Ratio a)

A ”class” of types

With these operations

Types which belong to this class

Page 58: Introduction to Programming in Haskell

ExamplesMain> 2 + 3.55.5

Main> True + 3ERROR - 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

Page 59: Introduction to Programming in Haskell

A Tricky One!

Main> sek (-10)-91.6642Main> sek -10ERROR - Cannot infer instance*** Instance : Num (Double -> Double)*** Expression : sek - 10

What’s going on?

Page 60: Introduction to Programming in Haskell

Operators AgainMain> :i +infixl 6 +(+) :: Num a => a -> a -> a -- class member

Main> :i *infixl 7 *(*) :: Num a => a -> a -> a -- class member

The binding power (or precedence) of an operator

– * binds tighter than + because 7 is greater than 6

Page 61: Introduction to Programming in Haskell

Giving ~== a Precedence

Main> 1/2000000 ~== 0ERROR - Cannot infer instance*** Instance : Fractional Bool*** Expression : 1 / 2000000 ~== 0

Wrongly interpreted as1 / (2000000 ~== 0)

Instead of(1/2000000) ~== 0

Page 62: Introduction to Programming in Haskell

Giving ~== a Precedence

• ~== should bind the same way as ==Main> :i ==infix 4 ==(==) :: Eq a => a -> a -> Bool -- class member

Main> 1/2000000 ~== 0True

infix 4 ~==x ~== y = abs (x-y) < 0.000001

Page 63: Introduction to Programming in Haskell

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

Page 64: Introduction to Programming in Haskell

Cases and Recursion

Page 65: Introduction to Programming in Haskell

Example: The squaring function

• Example: a function to compute

-- sq x returns the square of xsq :: Integer -> Integersq x = x * x

Page 66: Introduction to Programming in Haskell

Evaluating Functions

• To evaluate sq 5:– Use the definition—substitute 5 for x

throughout• sq 5 = 5 * 5

– Continue evaluating expressions• sq 5 = 25

• Just like working out mathematics on papersq x = x * x

Page 67: Introduction to Programming in Haskell

Example: Absolute Value

• Find the absolute value of a number

-- absolute x returns the absolute value of xabsolute :: Integer -> Integerabsolute x = undefined

Page 68: Introduction to Programming in Haskell

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 xabsolute :: Integer -> Integerabsolute x | x > 0 = undefinedabsolute x | x < 0 = undefined

Programs must often choose between

alternatives

Think of the cases! These are guards

Page 69: Introduction to Programming in Haskell

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 xabsolute :: Integer -> Integerabsolute x | x > 0 = xabsolute x | x < 0 = -x

Fill in the result in each case

Page 70: Introduction to Programming in Haskell

Example: Absolute Value

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

-- absolute x returns the absolute value of xabsolute :: Integer -> Integerabsolute x | x >= 0 = xabsolute x | x < 0 = -x

>= is greater than or equal, ¸

Page 71: Introduction to Programming in Haskell

Evaluating Guards

• Evaluate absolute (-5)– We have two equations to use!– Substitute

• absolute (-5) | -5 >= 0 = -5• absolute (-5) | -5 < 0 = -(-5)

absolute x | x >= 0 = xabsolute x | x < 0 = -x

Page 72: Introduction to Programming in Haskell

Evaluating Guards

• Evaluate absolute (-5)– We have two equations to use!– Evaluate the guards

• absolute (-5) | False = -5• absolute (-5) | True = -(-5)

absolute x | x >= 0 = xabsolute x | x < 0 = -x

Discard this equation

Keep this one

Page 73: Introduction to Programming in Haskell

Evaluating Guards

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

• absolute (-5) = -(-5)

absolute x | x >= 0 = xabsolute x | x < 0 = -x

Page 74: Introduction to Programming in Haskell

Evaluating Guards

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

• absolute (-5) = 5

absolute x | x >= 0 = xabsolute x | x < 0 = -x

Page 75: Introduction to Programming in Haskell

Notation

• We can abbreviate repeated left hand sides

• Haskell also has if then else

absolute x | x >= 0 = xabsolute x | x < 0 = -x

absolute x | x >= 0 = x | x < 0 = -x

absolute x = if x >= 0 then x else -x

Page 76: Introduction to Programming in Haskell

Example: Computing Powers

• Compute (without using built-in x^n)

Page 77: Introduction to Programming in Haskell

Example: Computing Powers

• Compute (without using built-in x^n)• Name the function

power

Page 78: Introduction to Programming in Haskell

Example: Computing Powers

• Compute (without using built-in x^n)• Name the inputs

power x n = undefined

Page 79: Introduction to Programming in Haskell

Example: Computing Powers

• Compute (without using built-in x^n)• Write a comment

-- power x n returns x to the power npower x n = undefined

Page 80: Introduction to Programming in Haskell

Example: Computing Powers

• Compute (without using built-in x^n)• Write a type signature

-- power x n returns x to the power npower :: Integer -> Integer -> Integerpower x n = undefined

Page 81: Introduction to Programming in Haskell

How to Compute power?

• We cannot write– power x n = x * … * x

n times

Page 82: Introduction to Programming in Haskell

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 x*x

3 x*x*x

Page 83: Introduction to Programming in Haskell

A Definition?

• Testing:Main> power 2 2ERROR - stack overflow

power x n = x * power x (n-1)

Why?

Page 84: Introduction to Programming in Haskell

A Definition?

• Testing:– Main> power 2 2– Program error: pattern match failure: power 2 0

power x n | n > 0 = x * power x (n-1)

Page 85: Introduction to Programming in Haskell

A Definition?

• Testing:– Main> power 2 2– 4

power x 0 = 1power x n | n > 0 = x * power x (n-1)

First row of the table

The BASE CASE

Page 86: Introduction to Programming in Haskell

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 = 1power x n | n > 0 = x * power x (n-1)

Page 87: Introduction to Programming in Haskell

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 = 1power x n | n > 0 = x * power x (n-1)

Page 88: Introduction to Programming in Haskell

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 = 1power x n | n > 0 = x * power x (n-1)

No circularity!

Page 89: Introduction to Programming in Haskell

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 = 1power x n | n > 0 = x * power x (n-1)

The STACK

Page 90: Introduction to Programming in Haskell

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 strategyin any programming language!

Page 91: Introduction to Programming in Haskell

Counting the regions

• n lines. How many regions? remove

one line ...

problem is easier!

when do we stop?

Page 92: Introduction to Programming in Haskell

The Solution

• Always pick the base case as simple as possible!

regions :: Integer -> Integerregions 0 = 1regions n | n > 0 = regions (n-1) + n

Page 93: Introduction to Programming in Haskell

Course Text Book

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.

uses Hugs instead of

GHCi

Page 94: Introduction to Programming in Haskell

Course Web Pages

URL:

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

Updated almost daily!

•These slides

•Schedule

•Practical information

•Assignments

•Discussion board