Int lengthList [ ] = 0">

Similar presentations

Lecture 9 Polymorphism, Overloading and Higher Order Functions 2 [1,2,3,4,5,6] :: [Integer] Prelude> ['a','b','c']++['d','e','f'] "abcdef" :: [Char] Prelude> "abc"++"def" "abcdef" :: [Char] Prelude> ["abc","def","ghi"]++["uvw","xyz"] ["abc","def","ghi","uvw","xyz"] :: [[Char]] What is the type of ++ : [a] -> [a] -> [a] Prelude> [1,2,3] ++ [4,5,6]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 3 lengthList (x:xs) = 1 + lengthList xs Main> lengthList ['a','b','c'] 3 :: Integer Main> lengthList [1,2,3,4,5,6] 6 :: Integer Main> lengthList [['a','b','c'],['d','e','f'],['g'],['h','i']] 4 :: Integer Main> lengthList ["abc","def"] 2 :: Integer What is the type of lengthList? [a] -> Int lengthList [ ] = 0

Lecture 9 Polymorphism, Overloading and Higher Order Functions 4 In polymorphism type variables are used, as in: [a] -> [a] -> [a] [a] -> Int (a,b) -> [a] Polymorphism: has many shapes. A function is polymorphic if it can operate on many different types. In polymorphism, the same function definition is used for all the types it is applied to. The variable a stands for an arbitrary type. Of course all the as in the first declaration above stand for the same type wheras in the third, a and b can be different types.

Lecture 9 Polymorphism, Overloading and Higher Order Functions 5 Overloading is another mechanism for using the same function name on different types. a = = b (a,b) = = (c,d) would require different definitions of = =. (a = = c) && (b = = d) An overloaded function has different definitions for different types.

Lecture 9 Polymorphism, Overloading and Higher Order Functions 6 Higher Order Functions

Lecture 9 Polymorphism, Overloading and Higher Order Functions 7 When we apply a function to all elements of a list, we say that we have mapped that function into the list. There is a Haskell built-in function called map that is used for this purpose. map f list = [ f x | x <- list] map f [ ] = [ ] map f (first:rest) = f first : map f rest Prelude> map odd [1,2,3,4,5] [True,False,True,False,True] Prelude> map (^2) [1,2,3] [1,4,9] Fact> map fact [3,4,5] [6,24,120] map: apply to all A higher order function takes a function as an argument or returns a function as a result.

Lecture 9 Polymorphism, Overloading and Higher Order Functions 8 map :: ( a -> b) -> [a] -> [b] Elements of the list to which the function is applied Elements of the output list that the function returns Type of map: input function input list output list

Lecture 9 Polymorphism, Overloading and Higher Order Functions 9 A function which doubles all the values in a list of integers: square :: Int -> Int square n = n^2 squareAll :: [Int] -> [Int] squareAll [ ] = [ ] squareAll (first : rest) = (square first) : (squareAll rest) double :: Int -> Int double n = n*2 doubleAll :: [Int] -> [Int] doubleAll [ ] = [ ] doubleAll (first:rest) = (double first) : (doubleAll rest) A function that squares all the values in a list of integers:

Lecture 9 Polymorphism, Overloading and Higher Order Functions 10 A function that returns a list of factorials of all the numbers in a given list of integers: There is a pattern that is repeated in all these definitions. Here is where we can use a higher order function. We may write a general function: doAll :: (Int -> Int) -> [Int] -> [Int] doAll f [ ] = [ ] doAll f (first : rest) = (f first ) : (doAll f rest) All we need is this one general definition and the definitions of each of the functions to be applied to each element. fact :: Int -> Int fact n = product [1..n] factAll :: [Int] -> [Int] factAll [ ] = [ ] factAll (first : rest) = (fact first) : (factAll rest)

Lecture 9 Polymorphism, Overloading and Higher Order Functions 11 double :: Int -> Int double n = n*2 square :: Int -> Int square n = n^2 fact :: Int -> Int fact n = product [1..n] doAll :: (Int -> Int) -> [Int] -> [Int] doAll f [ ] = [ ] doAll f (first : rest) = (f first ) : (doAll f rest) Main> doAll double [1,2,3,4] [2,4,6,8] Main> doAll fact [1,2,3,4] [1,2,6,24] Main> doAll square [1,2,3,4] [1,4,9,16]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 12 Alternatively, we could define all the functions in one line each using our higher order function doAll: doubleAll2 :: [Int] -> [Int ] doubleAll2 list = doAll double list squareAll2 :: [Int] -> [Int ] squareAll2 list = doAll square list factAll2 :: [Int] -> [Int ] factAll2 list = doAll fact list Main> factAll2 [1,2,3,4] [1,2,6,24] Main> doubleAll2 [1,2,3,4] [2,4,6,8] Main> doAll square [1,2,3,4] [1,4,9,16]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 13 We could even have used the built-in function map: doubleAll = map double where double x = 2*x Main> doAll double [1,2,3,4] [2,4,6,8] Main> map double [1,2,3,4] [2,4,6,8] Main> doAll fact [1,2,3,4] [1,2,6,24] Main> map fact [1,2,3,4] [1,2,6,24] Main> doAll square [1,2,3,4] [1,4,9,16] :: [Int] Main> map square [1,2,3,4] [1,4,9,16] Main> doubleAll [1,2,3] [2,4,6]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 14 map:: (Int -> Int) -> ([Int] -> [Int]) -- -> is right associative So, we can define the following functions which return a function as their result: doubleAll3 :: [Int] -> [Int ] doubleAll3 = map double squareAll3 :: [Int] -> [Int] squareAll3 = map square factAll3 :: [Int] -> [Int] factAll3 = map fact Main> squareAll3 [1,2,3,4,5] [1,4,9,16,25] :: [Int] We can think of map as a function which takes a function of type Int -> Int and returns a function of type [Int] -> [Int] or:

Lecture 9 Polymorphism, Overloading and Higher Order Functions 15 Function remove (removes an element from a list): remove _ [ ] = [ ] remove element (first : rest) = if element = = first then remove element rest else first : (remove element rest) We may want to write a function that removes all even or odd elements or elements that satisfy a certain condition. removeOdd [ ] = [ ] removeOdd (first:rest) = if odd first then removeOdd rest else first : removeOdd rest Main> removeOdd [1,2,3,4,5,6] [2,4,6] Filtering

Lecture 9 Polymorphism, Overloading and Higher Order Functions 16 removeEven [ ]=[ ] removeEven (first : rest)= if even first then removeEven rest else first : removeEven rest We can write a general function that does all of these. removeAll p [ ] = [ ] removeAll p (first : rest) = if p first then removeAll p rest else first : removeAll p rest Main> removeEven [1,2,3,4,5,6] [1,3,5]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 17 Main> removeAll odd [1,2,3,4,5,6] [2,4,6] Main> removeAll even [1,2,3,4,5,6] [1,3,5] We could have used filter to do all this rather than defining removeAll. This is another useful built-in function. It takes a property and a list and returns a list containing the elements that have that property. Main> filter odd [1,2,3,4,5,6] [1,3,5] Main> filter even [1,2,3,4,5,6,7] [2,4,6]

Lecture 9 Polymorphism, Overloading and Higher Order Functions 18 filter :: ( a -> Bool) -> [a] -> [a] The property is a function that returns a Bool Elements of the input list, the output list that the function returns and the type that the property works on Type of filter: input function input list output list

Lecture 9 Polymorphism, Overloading and Higher Order Functions 19 Definition of filter Fortunately, filter is a built-in function. If it wasnt a built-in function, we could have defined filter as follows. filter :: (Int -> Bool) -> [Int] -> [Int] filter p [ ] = [ ] filter p (first : rest) = if (p first) then first : (filter p rest) else filter p rest