CSCE 314 Programming Languages

advertisement
Recursion
Higher Order Functions
CSCE 314
Spring 2016
CSCE 314 – Programming Studio
More on Recursion: Multiple Arguments
• Functions can be defined with multiple arguments
• We’ve seen this already
insert :: Ord a => a -> [a] -> [a]
insert x [] = [x]
insert x (y:ys) | x <= y
= x:y:ys
| otherwise = y:insert x ys
Spring 2016
CSCE 314 – Programming Studio
More on Recursion: Multiple Recursion
• Functions can recursively call themselves multiple times
• Again, we’ve seen this before
quicksort :: [a] -> [a]
quicksort[] = []
quicksort (x:xs) = quicksort (smallerlist x xs) ++
[x] ++
quicksort (biggerlist x xs)
Spring 2016
CSCE 314 – Programming Studio
More on Recursion: Mutual recursion
• Two separate functions can each call each other
even 0 = True
even n = odd n-1
odd 0 = False
odd (n+1) = even n
-- Note: this (n+1) is an integer pattern
-- We can only use addition in an integer pattern
Spring 2016
CSCE 314 – Programming Studio
Recursion Overview
1.
2.
3.
4.
5.
Define the type
Enumerate the cases
Define the simple (base) cases
Define the other cases
Generalize and simplify
Spring 2016
CSCE 314 – Programming Studio
Example: product (product of list of ints)
1. Define the type
product :: [Int] -> [Int]
2. Enumerate the cases
product []
product (x:xs)
3. Define the simple (base) cases
product [] = 1
4. Define the other cases
product (x:xs) = x * (product xs)
5. Generalize and simplify
… -- can simplify with functions to be seen
Spring 2016
CSCE 314 – Programming Studio
Higher-order functions
• We’ve seen (via currying) that a function can produce a function as
output
• Functions can also take a function as input
• The map function is an example we’ve seen
map :: (a -> b) -> [a] -> [b]
• Can define map using a list comprehension
map f xs = [f x | x <- xs]
• Can define map using recursion
map f []
= []
map f (x:xs) = f x : map f xs
Spring 2016
CSCE 314 – Programming Studio
The Filter function
• Another higher-order function
• Takes in a function and a list, produces a list
• Function returns Bool, filter returns a list of those items that meet function
filter :: (a -> Bool) -> [a] -> [Bool]
• Can be defined using a list comprehension
filter p xs = [x <- xs, p x]
• Alternatively can be defined using a recursion
filter
filter
|
|
p [] = []
p (x:xs)
p x
= x : filter p xs
otherwise = filter p xs
Spring 2016
CSCE 314 – Programming Studio
Some other higher-order functions
• all
• True if and only if all elements of list meet some function
• any
• True if and only if some element of a list meets some function
• takeWhile
• Takes elements of a list while they meet some function
• dropWhile
• Drops elements of a list while they meet some function
Spring 2016
CSCE 314 – Programming Studio
Can you see a pattern?
sum []
= 0
sum (x:xs) = x + (sum xs)
v = 0
op = +
product []
= 1
product (x:xs) = x * (product xs)
v = 1
op = *
and []
= True
and (x:xs) = x && (and xs)
v = True
op = &&
f []
= v
f (x:xs) = x op f xs
Spring 2016
CSCE 314 – Programming Studio
The foldr function
• Captures this behavior
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr op v []
= v
foldr op v (x:xs) = op x (foldr op v xs)
• So, the earlier examples:
product ls = foldr (*) 1 ls
sum ls = foldr (+) 0 ls
length ls = foldr (\_ n -> 1 + n) 0 ls
Spring 2016
CSCE 314 – Programming Studio
Another way of thinking of foldr
• Each : in the list is replaced by the binary op
• [] is replaced by the given value v
• Example:
sum [1, 2, 3]
=
foldr (+) 0 [1, 2, 3]
=
foldr (+) 0 (1:(2:(3:[])))
=
1+(2(+(3+0)))
=
6
Spring 2016
CSCE 314 – Programming Studio
Other foldr examples
• The foldr function can actually represent a very wide set of functions
• Example: length
length
:: [a] -> Int
length []
= 0
length (_:xs) = 1 + length xs
Spring 2016
CSCE 314 – Programming Studio
foldr example for length
Example:
length [1, 2, 3]
= length (1:(2:(3:[])))
= 1+(1+(1+0)))
= 3
What is v?
0
What is op?
\_ n -> 1+n
So,
length = foldr (\_ n -> 1+n) 0
Spring 2016
CSCE 314 – Programming Studio
Why use foldr?
• Some recursive functions are simpler to define with foldr
• Properties of functions defined using foldr can be proved using
algebraic properties of foldr
• Advanced program optimizations are simpler if foldr is used in place
of explicit recursion
Spring 2016
CSCE 314 – Programming Studio
Next time
• More on higher-order functions
• foldl, composition
• Data types
Spring 2016
Download