1. Consider the following function definitions:
f1  = 0
f1(n:ns) = n + f1 ns
f2  = 1
f2 (n:ns) = n * f2 ns
f3  = 0
f3 (x:xs) = 2*x + f3 xs
f4  = 
f4 (ys:yss) = ys ++ f4 yss
f5  = 
f5 (c:cs) = toUpper cs : f5 cs
They all have a common pattern of behaviour.
(a) Write a higher-order function hof that captures this common behaviour
(b) Rewrite each of f1, f2, f3, f4, and f5 above, to be a call to hof with
(c) Is hof provided by the Haskell Prelude (under another name)?
If so, what is it called?
2. Given an expression datatype as follows:
data Expr = V String
| K Int
| Let String Expr Expr
| Sub Expr Expr
| Dvd Expr Expr
Given, also, a dictionary type with insert and lookup functions (full code not
type Dict = [(String,Int)]
ins :: String -> Int -> Dict -> Dict
lkp :: Monad m => String -> Dict -> m Int
Consider the following badly defined function eval:
eval :: Dict -> Expr -> Int
eval _ (K 0) = 0
eval d (V s) = getInt $ lkp s d
eval d (Let v e1 e2) = eval (ins v i d) e2 where i = eval d e1
eval d (Dvd e1 e2) = eval d e1 ‘div‘ eval d e2
getInt Nothing = (-42)
getInt (Just x) = x
(a) Describe, using an example, one way in which a call to function eval can
fail, with a Haskell runtime error that is not due to pattern-matching.
(b) Describe, using examples, two examples of different calls to function eval
that fail, with Haskell runtime pattern-matching errors. Note: such pattern
errors may occur in other functions called by eval.
(c) Rewrite the eval function above, by adding in any missing code, correcting
any code giving wrong answers, and adding proper error handling, with
informative error messages, using Monads. You will need to change the type
of the function, so your answer should give the revised type of the function.