# Exercises: Understanding folds ## Exercise 1 This will evaluate to: `(1*(2*(3*(4*(5*1))))`, so 1. Is not correct as the types are incorrect. 2. Will return the same result. 3. Will also return the same result. The latter two are the same because multiplication is commutative. ## Exercise 2 ``` fMul = flip (*) | ------- accumulator -------| foldl fMul 1 [1,2,3] = foldl fMUl (fMul 1 1) [2,3] = foldl fMul (fMul (fMul 1 1) 2) [3] = foldl fMul (fMul (fMul (fMul 1 1) 2) 3) [] = fMul (fMul (fMul 1 1) 2) 3 = 3*(2*(1*1)) = 6 ``` ## Exercise 3 1. They both traverse the spine from right to left. This evident by the `(x:xs)` pattern matching in both functions' definition. 2. They both force the rest of the fold as they are both recursive functions. 3. **True, `foldr` associates from the right and `foldl` assocatiates from the left.** 4. They are both recursive ## Exercise 4 (a) Catamorphism means to shape downwards and thus reduce structure. This is evident in the application of the folds which can reduce lists to a single value. ## Exercise 5 1. The zero value is missing: `foldr (++) "" ["woot", "WOOT", "woot"]` 2. The wrong zero value is used, a `Char` is expected: `foldr max 'a' "fear is the litle death"` 3. `and :: [a] -> Bool` is a function which takes an array and returns `True` if all values are `True`. This is not the same type as expected: `(a -> b -> b)`. **Should be: `foldr (&&) True [False, True]`** 4. The wrong zero value is used as this will always return `True`. Such is the nature of the `(||)`operator. Should be: `foldr (||) False [False, True]` 5. `foldl` expects a `b -> a -> b` function. `((++) . show) :: Show a => a -> [Char] -> [Char]`. If we use this function this means that, because the accumalator starting values `""` is of type `[Char]`, our fold function is: `[Char] -> [Char] -> [Char]` which does not fit, because this would mean our elements of the array should be of type `[Char]`. **It should be: `foldr (flip $ ((++) . show) "" [1..5]`** 6. The result of the `const` application should be the same type as the zero value (`Char`), but `const` returns the type of the second argument, in this case `Num a => a`. **It should be: `foldr (flip const) 'a' [1..5]`** 7. Same as (6). It should be: `foldr (flip const) 0 "tacos"` 8. This is similar to the previous questions. The `flip` is not needed here for the same reasons it is needed in (6) and (7). It should be: `foldl const 0 "burritos"` 9. Same as (8). It should be `foldl const 'z' [1..5]`