140 likes | 333 Views
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
E N D
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 aside Displaying 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 l.
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 Uncurry A 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 l-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.