Edit this page Backlinks This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== 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: <code haskell> foldr (*) 0 [1,2,3] = 1 * (2 * (3 * 0)) </code> 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: <code haskell> foldl (*) 0 [1,2,3] = ((0 * 1) * 2) * 3 </code> 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? ===== 4.2. Processing using higher-order functions ===== The following is an input test. You can add more examples to it: <code haskell> l = ["matei@gmail.com", "mihai@gmail.com", "tEst@mail.com", "email@email.com", "short@ax.ro"] </code> Use ''map'', ''foldr''/''foldl'', instead of recursive functions. Wherever possible, use functional composition and closures. 4.2.1. Remove uppercases from emails. (Do **not** use recursion). To be able to use character functions from the library, add ''import Data.Char'' at the beginning of the program. Use the Internet to find the appropriate character function. <code haskell> -- write this function as a closure rem_upper = </code> 4.2.2. Write a function which removes emails longer than a given size. Write the function as a **functional closure**. Use anonymous functions in your implementation, then think about how you can replace them by a functional composition of more basic functions. **Hint:** Write your code in steps. Start with the basic idea, then think about how you can write it better and cleaner. <code haskell> longer :: Int -> [String] -> [String] longer x = </code> 4.2.3. Count the number of emails longer than 12 characters. Use a fold, anonymous functions and functional composition. <code haskell> howmany = </code> 4.2.4. Split the list between first names and email domains. What ingredients (auxiliary functions) are necessary? Use either a fold or a tail-recursive function in your implementation. <code haskell> names_emails :: [String] -> [[String]] names_emails = </code> 4.2.5. Identify the list of the employed domain names (e.g. ''gmail.com''). Remove duplicates. Use no recursion and no additional prelude function apart from ''head'' and ''tail''. **Hint** think about the sequence of basic operations you want to perform and assemble them using functional composition. <code haskell> domains :: [String] -> [String] domains = </code> (!) 4.2.6. In some previous exercise you have, most likely, implemented a split function using ''foldr''. Implement one with ''foldl''. **Hint:** use an example together with the ''foldl'' implementation to figure out what the accumulator should do. <code haskell> splitl :: String -> [String] splitl = </code> 4.2.7. Write a function which extracts the domains from emails, without the dot part. (e.g. ''gmail''). Generalise the previous function ''splitl'' to ''splitBy:: Char -> String -> [String]'', and use it each time necessary, in your implementation. **Hint**: Wherever you want to mix pattern matching with guards, start with the patterns first. <code haskell> domain :: [String] -> [String] domain = </code>