# Haskell/Solutions/Lists III

← Back to Lists III

## Folds

* Exercises
* Define the following functions recursively (like the definitions for sum, product and concat above), then turn them into a fold:
* and :: [Bool] -> Bool, which returns True if a list of Bools are all True, and False otherwise.
* or :: [Bool] -> Bool, which returns True if any of a list of Bools are True, and False otherwise.
* Define the following functions using foldl1 or foldr1:
* maximum :: Ord a => [a] -> a, which returns the maximum element of a list (hint: max :: Ord a => a -> a -> a returns the maximum of two values).
* minimum :: Ord a => [a] -> a, which returns the minimum element of a list (hint: min :: Ord a => a -> a -> a returns the minimum of two values).
* Use a fold (which one?) to define reverse :: [a] -> [a], which returns a list with the elements in reverse order.
* Note that all of these are Prelude functions, so they will be always close at hand when you need them. (Also, that means you will want to use slightly different names for testing your answers in GHCi.)

## Scans

* Exercises
* Write your own definition of scanr, first using recursion, and then using foldr. Do the same for scanl first using recursion then foldl.
In the efficient scanr implementations above, we use head and tail as a way to avoid having to break down the list argument with pattern matching in the where clause only to assemble it back in the right-hand side. In the Pattern matching chapter, we will see how as-patterns allow us to reach the same effect without needing head.
* Exercises
* Define the following functions:
* factList :: Integer -> [Integer], which returns a list of factorials from 1 up to its argument. For example, facList 4 = [1,2,6,24].
* More to be added

## filter and list comprehension

* Exercises
* Write a returnDivisible :: Int -> [Int] -> [Int] function which filters a list of integers retaining only the numbers divisible by the integer passed as first argument. For integers x and n, x is divisible by n if (mod x n) == 0 (note that the test for evenness is a specific case of that).
* Exercises
* Write a function choosingTails :: [[Int]] -> [[Int]] using list comprehension syntax with appropriate guards (filters) for empty lists returning a list of tails following a head bigger than 5:choosingTails [[7,6,3],,[6,4,2],[9,4,3],[5,5,5]]
* -- [[6,3],[4,2],[4,3]]
* Does the order of guards matter? You may find it out by playing with the function of the preceding exercise.
The boolean conditions in a list comprehension are evaluated in order, so if you swapped the conditions like this:
If one of the l turned out to be an empty list the program would try to apply head on it, which would cause an error. Putting not (null l) first causes the program to, when it meets an empty list, to short-circuit the conditional - that is, ignore the second condition since the first one being false is enough for rejecting the list - thus avoiding doing head and the error that follows. Alternatively you may filter by pattern matching. Only non-empty lists match (l:ll) divided by the first element l followed by the possibly empty tail ll:
* Exercises
* Over this section we've seen how list comprehensions are essentially syntactic sugar for filter and map. Now work in the opposite direction and define alternative versions of the filter and map using the list comprehension syntax.
* Exercises
* Rewrite doubleOfFirstForEvenSeconds using filter and map instead of list comprehension.