functional programming lecture 11 - higher order functions
DESCRIPTION
Functional Programming Lecture 11 - higher order functions. Rule of Cancellation. If f :: t 1 -> t 2 -> … -> t n -> t and f is applied to arguments e 1 :: t 1 , … e k :: t k , where k < n then the resulting type is given by cancelling out the types t 1 to t k - PowerPoint PPT PresentationTRANSCRIPT
Functional ProgrammingLecture 11 -
higher order functions
Rule of Cancellation
If f :: t1 -> t2 -> … -> tn -> t
and f is applied to arguments
e1 :: t1, … ek :: tk, where k<n
then the resulting type is given by cancelling out the types t1 to tk
t1 -> t2 -> … -> tk -> tk+1 … -> tn-> t
i.e.
(f e1… ek ) :: tk+1 -> tk+2 … -> tn
Example: max :: Int -> Int -> Int
So, max 2 :: Int -> Int
Example: max :: Int -> Int -> Int
So, max 2 :: Int -> Int
(max 2) is just a function.
It is the function that takes the maximum of 2 and another number.
given:
max x y = if x>=y then x else y
then:
(max 2) y = if 2>=y then 2 else y
This is an example of partial evaluation. (The function max has been partially evaluated, to give another function, max 2.)
Function Application and ->
Associativity
Function application is left associative.
i.e. f x y = (f x) y
f x y = f (x y) !!
E.g.
max :: Int -> Int -> Int
max 2 3 = (max 2) 3
= max (2 3) (doesn’t make sense)
Function Application and ->
Associativity
Function space symbol -> is right associative.
i.e. a -> b -> c means a -> (b -> c)
not (a -> b) -> c
f :: a -> (b -> c)
g :: (a -> b) -> c
a
b f c (a->b) g c
E.g.
max :: Int -> (Int -> Int)
max 2 :: Int -> Int
Partial evaluation
When you partially evaluate a function, the new, resulting function must be enclosed in ‘(‘ .. ‘)’.
The new function is also called an operator section.
Examples
(+2) the function which adds 2 to its argument.
(2+) the function which adds 2 to its argument.
(>2) the function which compares its argument with 2.
(3:) the function the puts 3 at the front of a list.
(++”\n”) the function which puts a newline at the end of a string.
An asideDisplaying strings with newline characters.
‘\n’ is the newline character.
If you type in
> show “test\ntest”
the result is “test\ntest”
To display a string, and interpret the special symbols, use putStr :: String -> IO String.
If you type
> putStr “test\ntest”
the result is
test
test ::IO ()
Anonymous functions
Functions do not have to have names.
E.g.
\m -> n+m
This defines a function with one argument that returns the sum of n and that argument.
The arguments - given between \ and ->
The result - given after the ->.
\ stands for the Greek letter.
Using a Lambda-defined function
Define a function comp2 which applies a function f to each of its 2 arguments before applying function g to the results.
f
g
f
comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c)
f g resulting function
comp2 f g = \x y -> g (f x) (f y)
e.g.
comp2 sq add 3 4 => add (sq 3) (sq 4) => 9+16 => 25
Curry and UncurryA function which takes its arguments one at a time is said to be a curried function, or in curried form.
(Named after Haskell Curry, a logician who worked on combinatory logic and showed relationships to -calculus.)
E.g. max :: Int -> Int -> Int
is in curried form.
x
y
Most of the functions in this course so far have been curried.
A function which takes all its arguments “bundled” together as a tuple is said to an uncurried function, or in uncurried form.
E.g. maxUC :: (Int,Int) -> Int
is in uncurried form.
(x,y)
There is an obvious relationship between the curried and uncurried versions.
Namely, max x y = maxUC (x,y)
We can turn an uncurried function into a curried one, and vice-versa.
Suppose g is an uncurried function, g :: (a,b) ->c.
Then (curry g) :: a -> b -> c.
curry :: ((a,b) ->c) -> (a -> b -> c)
curry g x y = g (x,y)
Recall: function application is left assoc.
i.e. (curry g) x y = g (x,y)
Similarly,
suppose f is an curried function, f :: a -> b ->c.
Then (uncurry f) :: (a,b) -> c.
uncurry :: (a -> b -> c) -> ((a,b) ->c)
uncurry f (x,y) = f x y
So, (uncurry f) (x,y) = f x y
curry and uncurry are defined in the standard prelude.
E.g.
Prelude> uncurry (+) (2,1)3
Finally,
we would expect that curry and uncurry are inverses:
E.g.
curry (uncurry f) = f
uncurry (curry g) = g
It works for specific cases:
uncurry max = maxUC
curry maxUC = max
So, curry (uncurry max) = curry maxUC = max
uncurry (curry maxUC) = uncurry max = maxUC
But to prove it for an arbitrary function, requires induction.