Observe that these definitions following the same scheme as for lists: a mapping function applies its functional argumt to each element of the structure (in case of trees, the elements occur in the `Leaf`-constructor); a folding function describes how to transform a structure to an arbitrary type by specifying the function to replace the constructors with.

Now define the following functions using `mapTree` and `foldTree`, respectively.

>negateTree::TreeBool->TreeBool

>negateTreet=mapTreeelemFt

>where

>elemF=error"negateTree-elemF: Implement me!"

>

>sumTree::TreeInt->Int

>sumTreet=foldTreeleafFnodeFt

>where

>leafF=error"sumTree-leafF: Implement me!"

>nodeF=error"sumTree-nodeF: Implement me!"

>

>values::TreeInt->[Int]

>valuest=foldTreeleafFnodeFt

>where

>leafF=error"values-leafF: Implement me!"

>nodeF=error"values-nodeF: Implement me!"

3) The `foldList` function we defined in the lecture is predefined as `foldr :: (a -> b -> b) -> b -> [a] -> b` in Haskell. Reimplement the function `countElem` given in the lecture using `foldr`.

> countElem :: [] Int -> Int -> Int

> countElem [] elemToFind = 0

> countElem (val:list) elemToFind = if val == elemToFind

> then 1 + countElem list elemToFind

> else countElem list elemToFind

>countElem::[]Int->Int->Int

>countElemlistelemToFind=foldrconsFemptyFlist

>where

>consF=error"consF: Implement me!"

>emptyF=error"emptyF: Implement me!"

4) Given the following data type to represent arithmetic expression consisting of numeric values, an addition or multiplication.

>dataExprwhere

>Num::Int->Expr

>Add::Expr->Expr->Expr

>Mult::Expr->Expr->Expr

Give three exemplary values for arithmetic expressions that represent the expression given in the comment above.

>-- 1 + (2 * 3)

>expr1::Expr

>expr1=error"expr1: Implement me!"

>

>-- (1 + 2) * 3

>expr2::Expr

>expr2=error"expr2: Implement me!"

>

>-- (1 + 2) * (3 + 4)

>expr3::Expr

>expr3=error"expr3: Implement me!"

Define a function `value` that interpretes the `Expr`-data type by replacing the constructors `Add` and `Mult` with the concrete addition and multiplication operator.

>value::Expr->Int

>value=error"value: Implement me!"

For example, the function should yield the following result for the above expressions.

$> value expr1

7

$> value expr2

9

$> value expr3

21

Complete the signature for the mapping and folding function corresponding to the given type and implement these functions. The mapping function enables us to apply a function on the `Int` occurs in the `Num`-constructor. The folding function is a higher-order function that enables us to exchange the constructors of a given `Expr`-values with functions in order to compute a new value.

>mapExpr=error"mapExpr: Implement me!"

>

>foldExpr=error"foldExpr: Implement me!"

Now define `value` by means of `foldExpr`.

>valueFold::Expr->Int

>valueFold=error"valueFold: Implement me using `foldExpr`!"

5) Define a function `repeatValue` that computes an infinite list containing the value given as argument.

>repeatValue::a->[]a

>repeatValue=error"repeatValue: Implement me!"

Define a function `replicateValue` that takes an `n :: Int` as first argument and yields a list of length `n` containing the value given as second argument. Use `repeatValue` and `take` to define the function.

>replicateValue::Int->a->[]a

>replicateValue=error"replicateValue: Implement me using `repeatValue` and `take`!"