Commit 283f90e4 authored by Sandra Dylus's avatar Sandra Dylus

Add exercises regarding currying, partial application and functions as data

parent d01dd214
......@@ -76,3 +76,78 @@ A round might look like this! Note, that this is a two-player game: the user sta
Your guess is too large. Try again.
421
Congrats, you guessed the number!
5. Give the types for the following expressions.
a) `map ((+) 1)`
b) `[(+) 1, (*) 2, div 3]`
c) `foldr (+)`
d) `filter ((>) 4)`
e) `map (*)`
6. Which of these type signatures are valid for the function `map`.
a) `map :: (Int -> Bool) -> [] Int -> [] Bool`
b) `map :: (Int -> Bool) -> [] Bool -> [] Int`
c) `map :: (Bool -> String) -> ([] Bool -> [] String)`
d) `map :: Bool -> (Bool -> [] Bool -> [] Bool)`
e) `map :: String -> (Bool -> [] String) -> [] Bool`
7. We want to represent a set of `Int` values as function `Int -> Bool`, that is, the resulting `Bool` indicates if the argument passed is part of the set (for `True`) or not (for `False`).
> type Set = Int -> Bool
We can, for example, define the empty set as follows.
> empty :: Set
> empty = \_ -> False
Since our representation of `Set` is a function, the empty set is the function that yields `False` for every argument: because no value is part of the empty set! That is, the representation of our function is based on the "lookup"-function (we used the first idea in the lecture (see `Misc.hs` for reference)).
The idea becomes more clear when we "inline" the type synonym `Set` (here we use an additional comment) and rename the `set`-variable to `isInSet` to indicate that this argument is a function that yields a boolean value (i.e., a predicate).
> isElem :: Int -> Set -> Bool
> -- isElem val set = set val
> -- isElem :: Int -> (Int -> Bool) -> Bool
> isElem val isInSet = isInSet val
> -- Yields `True` if the given `Int`-value is part of the `Set`, `False` otherwise.
> isElem :: Int -> Set -> Bool
> isElem val isInSet = isInSet val
Based on this representation, define the following functions.
> -- Inserts the first argument to the `Set`.
> insert :: Int -> Set -> Set
> insert = error "insert: Implement me!"
>
> -- The new set should yield `True` if a value is in the first set or if it is part of the second set.
> union :: Set -> Set -> Set
> union = error "union: Implement me!"
>
> -- The new set should yield `True` if a value is in the first set and of the second set.
> intersection :: Set -> Set -> Set
> intersection = error "intersection: Implement me!"
For testing purposes, you want the following properties to hold.
$> isElem 5 empty
False
$> isElem 12435 empty
False
$> isElem 5 (insert 5 empty)
True
$> isElem 5 (union (insert 4 empty) (insert 3 empty))
False
$> isElem 4 (union (insert 4 empty) (insert 3 empty))
True
$> isElem 3 (union (insert 4 empty) (insert 3 empty))
True
$> isElem 4 (intersection (insert 4 empty) (insert 3 empty))
False
$> isElem 4 (intersection (insert 4 empty) (insert 4 empty))
You can also use the following function `fromList` to convert a list into a `Set` representation in order to test your implementation with "larger" sets. Note, that you need to implement `insert` first ; )
> toList :: [] Int -> Set
> toList list = foldr insert empty list
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment