This is an old revision of the document!
5. Algebraic Datatypes in Haskell
The type List
1. Define the type list with elements of type Integer
:
data IntList = ...
2. Define a function which computes the sum of elements of such a list:
isum :: IntList -> Integer
3. Define type polymorfic type List a
encoding lists with elements of type a
:
data List a =
4. Define a function which converts IntList
lists to List Integer
lists:
to_poly_list :: IntList -> List Integer
5. Define a function which displays lists. What type will this function have?
show_list = ...
Add the tree datatype definition from the lecture:
data Tree a = Void | Node (Tree a) a (Tree a) deriving Show
6. Implement the function flatten
:
flatten :: Tree a -> List a
7. Define list concatenation over type List a
:
app :: (List a) -> (List a) -> (List a)
8. Define the function tmap
which is the Tree a
correspondent to map::(a→b) → [a] → [b]
.
9. Define the function tzipWith
:
tzipWith :: (a -> b -> c) -> (Tree a) -> (Tree b) -> (Tree c)
10. Define the function tfoldr
:
tfoldr :: (a -> b -> b) -> b -> Tree a -> b
Before implementing it, consider what should tfoldr (+) 0
do, and how should this value be computed.
11. Implement the flattening function using tfoldr
:
tflatten = ...
Sometimes, instead of doing pattern matching in a function definition, e.g.:
f [] = "Empty" f (x:y:xs) = "At least two" f _ = "Something else"
it is useful to do this in the body of the function, or in another expression. This can be done using the case
instruction. Example:
f l = case l of [] -> "Empty" (x:y:xs) -> "At least two" _ -> "Something else"
12. Consider the following definition of natural numbers extended with the value Infinity
:
data Extended = Infinity | Value Integer
Define a function which computes the sum of two Extended
values:
extSum :: Extended -> Extended -> Extended extSum v v' =
(Question: can you implement it with a single case
expression?)
13. Define a function which computes the equality of two Extended
values:
equal :: Extended -> Extended -> Bool
The polymorphic datatype:
data Maybe a = Nothing | Just a
which is part of the Haskell default library is useful for error handling. For instance, if a computation fails, a function may return Nothing
. If the computation returns a result x
of type a
, then the function will return a value Just x
.
14. Implement the function lhead
which behaves like head
but returns Nothing
if the argument of the function is the empty list:
lhead :: List a -> Maybe a
15. Implement the function ltail