Download Composite Datatypes --- Lists and Tuples

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts

Scala (programming language) wikipedia, lookup

Falcon (programming language) wikipedia, lookup

C Sharp (programming language) wikipedia, lookup

Standard ML wikipedia, lookup

Transcript
This session
Composite Datatypes — Lists and Tuples
After this session, you should be able to handle composite data
types in Haskell
COM1022 Functional Programming Techniques
defining the types
defining functions on the types
using standard Prelude functions
Professor Steve Schneider
Reference:
Thompson, Chapter 5
University of Surrey
Autumn 2009 Week 11
[based on slides by Dr Hans Georg Schaathun]
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
1 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Introduction
Autumn 2009 Week 11
3 / 42
Introduction
Shopping basket
Tuples versus Lists
as an example
The items are tuples: (String, Int)
A basket contains many items
Fixed number of entries (2)
Combining different data types (String and Int)
Each item comprises a description and a quantity
Sample items:
The basket is a list: [ (String, Int) ]
( "Salt (1lb)", 3 )
( "Sugar (1kg)", 5 )
Variable number of items
Same data type for elements of the list: (String,Int)
Sample Shopping Basket:
Any data type can be used to define tuples and strings
[( "Salt (1lb)", 3 ), ( "Sugar (1kg)", 5 ),
( "Orange", 12 ) ]
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
4 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
5 / 42
Introduction
Tuples
Defining data types
Other tuples
Tuples can have any number of items
We can define our own data types:
type Item = (String,Float,String)
e.g. ("Oranges",3.5,"lbs")
type Item = (String,Int)
type Basket = [Item]
... or
This establishes synonyms for common data types
type Item = (String,String,Int,String,String)
e.g.
("COM1022",
"Functional Programming",
20,
"HGS",
"http://www.computing.surrey.ac.uk/teaching
/current/com1022/")
synonyms makes code more intuitive and readable
can be used interchangably (when readability is not an issue)
All type identifiers have to start with a Capital
The built-in type String is defined as
type String = [Char]
i.e. a String is a special case of lists
Professor Steve Schneider
Uses of tuples
Composite Datatypes — Lists and Tuples
Tuples
Autumn 2009 Week 11
6 / 42
Professor Steve Schneider
Uses of tuples
Composite Datatypes — Lists and Tuples
Tuples
Why do we use tuples?
Autumn 2009 Week 11
8 / 42
Functions over tuples
Pattern matching
A known example
Related information should be bundled together
For instance, a data base
factorial 0 = 1
factorial n = factorial (n-1)
Person needs: name, address, date of birth etc.
Library book needs: title, author, shelfmark, ISBN, etc.
Several function definitions
Represent each person/book by a tuple
Different patterns for the arguments
one variable identifies one person/book
each piece of information is one component of the tuple
Haskell will use the first applicable pattern
Every person/book has the same components
1
2
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
9 / 42
0 is a literal, and matches only a numerical 0.
n is an identifier and matches any value
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
11 / 42
Tuples
Functions over tuples
Tuples
Tuple patterns
Functions over tuples
Selector functions
an example
Introducing tuples, more complex patterns become possible
itemType :: Item -> String
itemType (x,_) = x
itemType is a selector function
(x,_) matches any pair
extracts one of several items
x matches the first item
_ matches anything but no identifier is assigned
selector functions are often needed
built-in selector functions
fst (x,_) = x
snd (_,y) = y
quantity :: Item -> Int
quantity (_,x) = x
Doubling the quantity:
double :: Item -> Item
double (x,y) = (x, 2*y)
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Tuples
Autumn 2009 Week 11
12 / 42
Composite Datatypes — Lists and Tuples
Functions over tuples
Lists
Pattern matching for readibility
Autumn 2009 Week 11
13 / 42
The power of lists
The generality of lists
For every type t there is a list type [t]
Consider a function adding the components of a pair
addPair ::
Professor Steve Schneider
Lists of Float: [Float]
Lists of lists of Float: [[Float]]
Lists of tuples: [(Float,[Float],Int)]
Lists of functions: [ Int -> Int]
Lists of functions on lists: [ [Int] -> Float ]
(Int,Int) -> Int
Selector functions can solve the problem
addPair p = fst p + snd p
Pattern matching tends to make it more readable
There is no limit
addPair (x,y) = x + y
But each list type has one specific constituent type
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
14 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
16 / 42
Lists
The power of lists
Lists
The strength of functional programming
List comprehension
Systematic definition of large lists
Large lists can be defined systematically
similar to normal mathematical set notation
Lists are at the heart of functional programming
For instance
The strength is in the flexible functions possible on lists
... that is ...
[1..9] = [1,2,3,4,5,6,7,8,9]
[2*x | x<-[1..8] ] = [2,4,6,8,10,12,14,16]
polymorphism – to be explored later in this session
higher-order functions – later in the course
The latter example is known as list comprehension
In maths notation it looks like
{1 . . . 9}
{2x|x ∈ {1 . . . 8}}
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Lists
Autumn 2009 Week 11
17 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
List comprehension
Lists
List comprehension
Autumn 2009 Week 11
19 / 42
List comprehension
Multiple generators
Sometimes more than one generator is used
suits = [ "Spades", "Hearts", "Diamonds", "Clubs" ]
honours = [ "Ace", "King", "Queen", "Knave" ]
goodCards = [ (x,y) | x <- suits, y <- honours ]
ex = [1..8]
[2*x | x<-ex]
List comprehension generates a list based on another list
the variable x is called a generator
What does goodCards evaluate to?
The general form is [expression | condition]
expression is evaluated for every value of the generator(s)
where the generator(s) have to satisfy the condition
Main> goodCards
[("Spades","Ace"),("Spades","King"),("Spades","Queen"),
("Spades","Knave"), ("Hearts","Ace"),("Hearts","King"),
("Hearts","Queen"),("Hearts","Knave"),("Diamonds","Ace"),
("Diamonds","King"),("Diamonds","Queen"),("Diamonds","Knave"),
("Clubs","Ace"),("Clubs","King"), ("Clubs","Queen"),
("Clubs","Knave")]
The simplest condition x ∈ ex (x<-ex)
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
20 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
21 / 42
Lists
List comprehension
Lists
Complex conditions
List comprehension
New Scientist Enigma 1574 (5 December 2009)
Doubly square dates.
4 April 2001 was the first doubly square date of the century
because whether written in the order day.month.year or
month.day.year (in each instance with two digits in each
element) it comes out as 04.04.01, and 40401 = 2012 .
Suppose we have a function
isEven n = (n ‘mod‘ 2 == 0)
which is True if and only if n is even
ex = [2,5,8,12]
[ 2*n | n <- ex, isEven n, n > 3 ]
Still with two digits for each element, there are some doubly
square dates for which the square that comes from the order
day.month.year is not the same as the square that comes
from the order month.day.year. This is the case for each of
the next two doubly square dates after 4 April 2001. What are
those two dates?
now only even ns larger than 3 are used
the result is [16,24]
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Lists
Autumn 2009 Week 11
22 / 42
Professor Steve Schneider
List comprehension
Composite Datatypes — Lists and Tuples
Lists
Doubly square dates
Autumn 2009 Week 11
23 / 42
List comprehension
Pythagoras
dsdates :: [(Int,Int,Int)]
Pythagorean triads: integer sides of a right angled triangle.
dsdates = [(x,y,z) | z <- [1..99],
y <- [1..12],
x <- [1..31],
dsquare (x,y,z)]
triads :: Int -> [(Int,Int,Int)]
triads n = [(x,y,z) | z <y <x <(x*x
dsquare :: (Int,Int,Int) -> Bool
[1..n],
[1..z-1],
[1..y-1],
+ y*y == z*z)]
dsquare (x,y,z) =
(square (10000*x + 100*y + z))
&& (square (10000*y + 100*x + z))
square ...
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
24 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
25 / 42
Lists
List comprehension
Lists
Conditions with pattern matching
Functions on lists
List patterns
Simple patterns
Normal rules for pattern matching apply in list
comprehension
Pattern matching applies to lists as to tuples
For instance
ltest [0,a] = a
ltest [0,a,b] = a + b
ltest [a,_] = a
addPairs :: [(Int,Int)] -> [Int]
addPairs pl = [ x+y | (x,y) <- pl ]
addPairs [ (2,3), (2,5), (3,1) ]
[ 2+3, 2+5, 3+1 ] = [5,7,4]
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Lists
... but such patterns dictate the list length
Autumn 2009 Week 11
26 / 42
Professor Steve Schneider
Functions on lists
Composite Datatypes — Lists and Tuples
Lists
List patterns
Autumn 2009 Week 11
28 / 42
Autumn 2009 Week 11
30 / 42
Functions on lists
Maximum
Simple patterns
The list constructor : can be used for patterns
x:xs
Maximum
x is one element (the first)
xs is the rest of the list
maxm
maxm
maxm
|
|
Note that xs is one element shorter than x:xs
this is the basis for simple recursion
For instance, return the first non-zero element
:: [Int] -> Int
[x] = x
(x:xs)
x > maxm xs = x
otherwise
= maxm xs
ltest (0:xs) = ltest xs
ltest (x:xs) = x
Is there a bug in the ltest code above?
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
29 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Lists
Functions on lists
Lists
Functions on lists
Remove duplicates from a list I
Remove duplicates from a list II
Remove an element from a list: a recursive definition
Remove duplicates from a list: a recursive definition
remove :: Int -> [Int] -> [Int]
remdups :: [Int] -> [Int]
remove n [] = []
remdups [] = []
remove n (x:xs)
| n == x
= remove n xs
| otherwise = x:(remove n xs)
remdups (x:xs) = x:(remdups (remove x xs))
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Lists
The recursive case: retain the first element x of the list, remove further
occurrences of x from the rest of the list, and apply remdups to it.
Autumn 2009 Week 11
31 / 42
Functions on lists
[Int] -> [Int]
e.g. sort [3,6,2,8,5] = [2,3,5,6,8]
Recursion: if we can sort lists of length less than n, how can we
sort lists of length n?
Seeing a way to do this will be the basis for a recursive definition.
Base case: sort [x] = [x]
Recursive case: sort (x:y:xs) = ???
...assume we can already do sort (y:xs) and that we have
z:zs = sort (y:xs)
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
32 / 42
Polymorphism
Polymorphism
Given a list of integers, how do we rearrange that list so it includes
the same elements but sorted in order?
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Polymorphism
Challenge: Sorting a list
sort ::
Professor Steve Schneider
Autumn 2009 Week 11
polymporphism ∼ «has many shapes»
Polymorphic functions apply to different types of data
For instance the length of a list
length :: [a] -> Int
where a is a type variable
i.e. a matches any type
Or concatenation
(++) :: [a] -> [a] -> [a]
a is an arbitrary type
but all three instances of a are the same type
Polymorphism saves us the trouble of typing several similar
definitions
33 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
35 / 42
Polymorphism
Polymorphism
Polymorphism
For example
Polymorphism
Polymorphism versus Overloading
Polymorphism and Overloading both allow
The length function could be defined as
same function name on different types
length :: [a] -> Int
length [] = 0
length (x:xs) = 1 + length xs
However, there is a key difference
Polymorphism has a single function definition
applicable to several types
Overloading allows different definitions
This is an example of recursion over lists
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
for different types
Autumn 2009 Week 11
36 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Strings
Autumn 2009 Week 11
37 / 42
Strings
Strings
Special Characters
A special case of lists
String is a synonum for [Char]
All polymorphic list functions apply to strings
Special characters represented by escape sequences
Newline \n
Tab \t
Quotes (\" — \’)
Backslash \\
map, foldr, ++
Main> [ ’a’, ’b’, ’c’ ]
"abc"
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
38 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
39 / 42
Strings
Conclusion
Printing Special characters
Summary
Summary
Hugs displays the escape sequences
Not the special characters
Main> "Item\tQuantity\nApples\t4\nOranges\t12\n"
"Item\tQuantity\nApples\t4\nOranges\t12\n"
Much of the power of functional languages is the list capabilities
Simple expressions to define lists
List comprehension
An I/O function is needed to get the proper display
Pattern matching
This is the putStr function
Main> putStr "Item\tQuantity\nApples\t4\nOranges\t12\n"
Item
Quantity
Apples 4
Oranges 12
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
40 / 42
Professor Steve Schneider
Composite Datatypes — Lists and Tuples
Autumn 2009 Week 11
42 / 42