====== 4. Higher order functions ====== ===== 4.1. Map, foldl, foldr, filter, zipWith ===== ==== Map ==== The function ''map'' has signature: ''(a->b) -> [a] -> [b]''. It takes as parameter: - a **transformer** function ''f :: a->b'' - a list of objects of type ''a'' It returns: - a list of transformed objects of type ''b'' 4.1.1. Write a function which takes a list of integers and adds 4 to **each element**. 4.1.2. Write a function which takes a list of strings and adds a whitespace at the **beginning** of each string. 4.1.3. Write a function which takes a value k, a list of **strings** and returns a list with the first k characters of each string. ==== Filter ==== The function ''filter :: (a -> Bool) -> [a] -> [a]'' takes as parameter: * a **predicate** (or condition) of type ''(a -> Bool)'' * a list of elements of type ''a'' It returns: * a list of filtered elements using the predicate. 4.1.4. Write a function which removes all strings which are equal to the empty string. 4.1.5. Write a function which takes a list of strings and returns only those which start with a capital. ==== Foldr ==== The function ''foldr'' has type ''(a -> b -> b) -> b -> [a] -> b''. It takes as parameter: * a **binary** operation ''a -> b -> b''. It takes a "list" element of type ''a'', and an **accumulator** of type ''b'' and returns an element of type ''b'' * an **accumulator** (or initial value) of type ''b'' * a list with elements of type ''a'' It returns: * a **folded** (or reduced) value of type ''b''. Example: foldr (*) 0 [1,2,3] = 1 * (2 * (3 * 0)) 4.1.6. Write a function using foldr which computes the product of a list of integers. 4.1.7. Write a function which computes the maximum of a list of **positive** integers using foldr. 4.1.8. Write a function which concatenates a list of strings using foldr. ==== Foldl ==== The function ''foldl'' has type ''(b -> a -> b) -> b -> [a] -> b''. It takes as parameter: * a **binary** operation ''b -> a -> b''. It takes an **accumulator** of type ''b'', a "list" element of type ''a'' and returns an element of type ''b'' * an **accumulator** (or initial value) of type ''b'' * a list with elements of type ''a'' It returns: * a **folded** (or reduced) value of type ''b''. Unlike foldr, foldl reduces element in a different order: Example: foldl (*) 0 [1,2,3] = ((0 * 1) * 2) * 3 4.1.9. Write a function which uses foldl to check if an element is member of a list. 4.1.10. Write a function which uses foldl to implement the reversal of a list. ==== zipWith ==== 4.1.11. Use ''ghci> :t zipWith'' to inspect the type of ''zipWith''. Think about a possible example to run this function. What does it do?