# My solution to a Haskell exam

Please keep in mind, that all the source is untested (as it would be in a real exam situation). If there are errors, I'm happy if you let me know.

## Exercise 1

Give the type of the following expressions: `Just`

, `Just Nothing`

,
`Just (Just True)`

, `Just Just`

, `Just (Just Just)`

I think, the easiest way to do this, is by starting to guess the type of the term in brackets. At least for the more complicated ones.

If the first type is clear, the rest should be straight forward.

## Exercise 2

Write a function `catMaybes :: [Maybe a] -> [a]`

, that drop's all
the `Nothing`

values and only returns a list of the value within
the `Just`

constructor.

Here you only have to parse the list, item by item. If you
encounter a `Just`

constructor, take the value inside and put it in
the list. Than go on with the rest-list.

## Exercise 3

Write a function `mapMaybe :: (a -> Maybe b) -> [a] -> [b]`

. The
supplied function produces `Maybe`

values. If it produces an ```
Just
b
```

, then put the `b`

into the result list, otherwise do nothing.

## Exercise 4

Write a function `id :: a -> a`

, that returns arguments unchanged.

## Exercise 5

Write a function `null :: [a] -> Bool`

, that returns `True`

, if the
list is emtpy.

## Exercise 6

Write a function `map :: (a -> b) -> [a] -> [b]`

, that applies the
supplied function to all the arguments of the supplied list.

## Exercise 7

Write a function `concat :: [[a]] -> [a]`

, that tears down a list of
lists, to a simple list.

## Exercise 8

Write a function `length :: [a] -> Int`

, that returns the length of a list

## Exercise 9

Write a function `any :: (a -> Bool) -> [a] -> Bool`

, that takes a
predicate function, and returns true, if in the list is any element
that supports that.

## Exercise 10

Write a function `all :: (a -> Bool) -> [a] -> Bool`

, that takes a
predicate function, and returns true, only if all elements of the
list support the predicate function.

## Exercise 11

Write a function `concatMap :: (a -> [b]) -> [a] -> [b]`

, that
supplies a function to any element of a list, and concat's the
results.

## Exercise 12

Write a function `filter :: (a -> Bool) -> [a] -> [a]`

, that
returns only those elements of a list, that support the predicate.

## Exercise 13

How to use the `filter`

function, to get all the strings from a
list of string, that contain an 'a'?

## Exercise 14

How to use the `filter`

function, to get a list of lists, where all
lists are longer than 10?

## Exercise 15

Give the type of the following expression: `filter (=`

'a')=,
`filter ((>10) . length)`

, `filter ((=`

'a') . head . fst . fst)=

## Exercise 16

The following data type describes a tree. It's nodes hold lists of values, and it's leafs might hold values.

- What is the
*kind*of`Tree`

? What is the type of`Br`

, and of`Lf`

?

The kind is of *order* 2, because there is only one type needed to
produce a second one.

With the type constructor `Br`

, something of type `Tree a`

is
produced. In order to do so, a `[a]`

, and 2 `Tree a`

are needed.

- Write a function
`tree2lst`

, that writes all values of a tree into a list.

- Write an instance of
`Eq`

for`Tree a`

These trees are equal, if there are two branches, with equal lists, and also if both sub-trees are equal, too.

They are also equal, if they are two leafs with equal value, and also if both have no value.

Otherwise, the trees are unequal.

- Write an instance of
`Functor`

for`Tree a`

Ok, `Functor`

want's you, to write an `fmap`

function. That function
awaits a function, which is executed on every value inside the tree.

The function is mapped over the list of a branch, and is propagated to the sub-trees via fmap.

The propagation stops at the leafs.

- Write a fold function
`foldTree`

for the`Tree a`

type

To fold something means, to tear a structure down. Therefore a
function is used, that can consume a value of the tree at a time. That
value, together with the result *so far*, is computed into the next
result *so far*.

For the first calculation, a initial value is also needed.

That initial value is used, in combination with the left sub-tree, to
calculate the result *so far* from the left tree. That result is used,
together with the right tree, to calculate the next result *so far*.

At last, that result is supplied to a fold function for lists, to calculate a final result.

With the help of

`foldTree`

, write a`sumTree`

function, that sumsall up all values inside the tree.

If `Foldtree`

is supplied with the addition function, and 0, the
initial calculation would be a value of the tree plus 0. That is then
added to the next value of the tree, until all values are
consumed. The last result is the final result.

## 17 With the data type

- Write an instance of
`Functor`

for`Either`

Again, `Functor`

needs a definition of the `fmap`

function. `fmap`

takes a function, that transforms an inner value, and a capsuled
value. It executes the function on the inner value of the capsule, and
puts the result back into the capsule.

Keep in mind, that you only have to take action on the `Right`

side,
because the `Left`

side is constrained to `a`

.

- Write an instance of
`Monad`

for`Either`

For `Monad`

a combination operator and a capsule operator must be
defined. Again, only the `Right`

side must be calculated, the `Left`

side is constrained.

The capsuling returns everything supplied also only to the `Right`

constructor.

## 18 Write monadic versions for list functions

- Write a monadic version
`filterM`

The function returns just a monadic version of the empty list, if the empty list is supplied.

For all other lists, the predicate function is executed on the first
element of the list. The result is passed into a new function. There
`a`

is added to the result list, only if `f a`

resulted in true.

- Write a monadic version
`mapM`

The scheme is the same here as in `filterM`

. The supplied monadic
function is applied to the first element of the list. The calculated
value is then bound, via a lambda expression, to the identifier
`n`

. `mapM`

is executed on the rest list. The value `n`

is than
appended to the result of the inner `mapM`

.

- Write a monadic version
`zipWithM`

Again, the schema is here exactly the same, as in the previous two. Calculate the first value, and bind it to the rest values.

- Write a function, that applies a function embedded in a monad, to values inside that monad.

Here, obviously `f`

must be executed on `x`

. Therefore both are
catched within the prime variants and are then applied.

The result is then packed back inside the monad.

## 19 Write text file processing functions

Assume, that there is a `test.txt`

file in the actual
directory.

- Write a program to count the lines within
`test.txt`

The first thing would always be, to read the file into `file`

. Then
the `lines`

function splits the `file`

string into it's
lines. After that, the `length`

is the line count.

- Write a function, that counts the number of words with more than 2 letters.

The file is read. Then the content is split up into words. With
`filter`

only the words, that have a length that is greater 2 ```
(>2)
. length
```

, are returned. The length of that list is the number of such
words.

- Write a function that prints the lines that contain an 'a'

Here the file is read and split up into it's lines. With filter, some
lines are filtered out. Which, is determined by a fold, that returns
`False`

if there is no 'a' within the line, and `True`

otherwise. These lines are then printed with `putStrLn`

.

- Write a function, that returns the longest line, that does not contain an 'a'.

First of all, the `fold fn`

function from 19.3 is here put into a
helper function, called `lineContains`

. That function takes a
character and a string and returns a boolean value, that indecates, if
the char is within that line.

Then the actual function reads the file, and splits it into lines. These lines are then filtered for lines that do not contain an 'a'.

That result contains all possible lines and another fold is used to break it down to only one line, the longest line.

- Write a function, that returns the number of words of the line with the most words.

Again, a simple fold is used, to return the number of words of the longest line. The fold compares the actual highest number of words, with that of the next line. Only if the next line contains more words, than the actual line, the actual number is taken.

- Write a function, that returns the longest word

Here is the file split into it's words. Then with a fold, only the longest word is passed.