Exercises
- The prelude PreludeList of Haskell98 contains a number of
functions that are defined by means of a foldr (a
catamorphism). Find at least five other functions in the prelude
that can be defined as a catamorphism on lists, and give their
definitions as a catamorphism.
- Catamorphisms can be defined in terms of function
cata
:
cata :: Regular d => (FunctorOf d a b -> b) -> (d a -> b)
cata phi = phi . F (cata phi) . out
Define the functions out
and F
(and
probably a new type) in Haskell on the datatypes
[a]
and Tree a
(see Thesis page 2),
such that the following definitions define the catamorphisms on
these datatypes.
cataTree phi = phi . fTree (cataTree phi) . outTree
cataList phi = phi . fList (cataList phi) . outList
- Define function
anaList :: (b -> Maybe (a,b)) -> (b ->
[a])
so that anaList f
is an anamorphism for
lists.
- Define function
zip'
(a variant of the prelude
function zip
):
zip' :: ([a],[b]) -> [(a,b)]
as an anamorphism.
- Fusion:
- Write function
length
as a [a]
catamorphism.
- Write function
insertion_sort
as a
[a]
catamorphism.
- Use fusion to prove that
length . insertion_sort = length
- Define
minimum
and reverse
as
catamorphisms on Tree a
. Instantiate (mechanically,
don't try to be clever!) the banana split theorem to obtain a
Tree a
catamorphism for the split of
minimum
and reverse
in Haskell.
The result can be further simplified - try to do it algebraically.
- The datatype
PairList a
is defined by
data PairList a = PLNil
| PLCons a (PairList (a,a))
- Define, in Haskell, a map on this datatype. (Hint: use
so-called polymorphic recursion.)
- Can you instantiate the polytypic map on this
datatype?
- Define a polytypic function that calculates the maximum
`depth' of a value of any datatype.
depth :: d a -> Int
For example,
depth (Just 1) = 1
depth [5, 2, 1] = 3
depth (Bin (Leaf 6) (Bin (Bin (Leaf 3)(Leaf 6)) (Leaf 8))) = 3.
- Consider the function
flatten
defined in PolyLib.
Since this definition uses ++
in the
g*h
case, it is rather inefficient: it is quadratic
in the size of its argument. The standard trick to obtain a
linear-time program is to use an `accumulating parameter':
replace flatten
by a function
flatten'
flatten = flatten' []
flatten' :: d a -> [a] -> [a]
Define the polytypic function flatten'
.
- Define
balance :: [a] -> Tree a
as a
Tree-anamorphism.
- Define
mapTree
using cataTree
.
Resources
Misc. definitions
(-*-) :: (a -> c) -> (b -> d) -> ( (a,b) -> (c,d))
(-+-) :: (a -> c) -> (b -> d) -> (Either a b -> Either c d )
f -*- g = \(x,y) -> (f x, g y)
f -+- g = either (Left . f) (Right . g)
split :: (a->b) -> (a->c) -> (a-> (b, c ))
split f g = \x-> (f x, g x)
Theorem:
split (cata f) (cata g) = cata (split (f . fmap2 id fst) (g . fmap2 id snd))
Examples
Solutions
You can compare your answers with some solution
sketches.
Last modified: Wed Oct 18 12:47:31 MET DST 2000
by
Patrik Jansson /
NOpatrikjSP@AMchalmers.se