This is an old revision of the document!
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