Exercises for Week 5: Higher-Order Functions and Test Data GenerationHere are some exercises designed to help you practice programming with higher-order functions and test data.
Please prepare yourself for these exercises by printing them out, and also printing out the code samples and documentation that is referred to by links.
If you do not have time to do all these exercises, don't worry. The exercises are intended to provide enough work to keep the most experienced students busy. If you do all exercises marked with an (*) you have probably understood this week's material.
Some of the exercises below involve writing QuickCheck properties. The parts of those exercie that require you to run QuickCheck are obviously not so suited for doing in the group exercises. These parts you can do yourself at home, either before the exercise session (as preparation), or after.
1 (*). Exercises from chapter 9-10 of The Craft of Functional Programming
(*) Define the
(*) What does
map (+1) (map (+1) xs)do? Can you conclude anything in general about properties of
map f (map g xs), where
gare arbitrary functions?
Give the type of, and define the function
iter n f x = f (f (... (f x)))
ntimes on the right-hand side of the equation. For instance, we should have
iter 3 f x = f (f (f x))and
iter 0 f xshould return
What is the type and effect of the following function?
\n -> iter n succ
succis the successor function, which increases a value by one:
(*) How would you define the sum of the squares of the natural numbers 1 to
How does the function
mystery xs = foldr (++)  (map sing xs) where sing x = [x]
idis the polymorphic identity function, defined by
id x = x, explain the behavior of the expressions
(id . f) (f . id) (id f)If
fis of type
Int -> Bool, at what instance of its most general type
a -> ais
idused in each case?
Define a function
composeListwhich composes a list of functions into a single function. You should give the type of
composeList, and explain why the function has this type. What is the effect of your function on an empty list of functions?
(*) Define the function
which reverses the order in which its function argument takes its arguments.
flip :: (a -> b -> c) -> (b -> a -> c)
The following example shows the effect of
flip div 3 10033
Do not forget to write suitable QuickCheck properties checking that your definitions behave as expected.
(To QuickCheck properties that take function arguments, make sure to
2 (*). List Comprehensions and Higher-Order FunctionsCan you rewrite the following list comprehensions using the higher-order functions
filter? You might need the function
[ x+1 | x <- xs ]
[ x+y | x <- xs, y <-ys ]
[ x+2 | x <- xs, x > 3 ]
[ x+3 | (x,_) <- xys ]
[ x+4 | (x,y) <- xys, x+y < 5 ]
[ x+5 | Just x <- mxs ]
Can you do it the other way around? I.e. rewrite the following expressions as list comprehensions.
map (+3) xs
filter (>7) xs
concat (map (\x -> map (\y -> (x,y)) ys) xs)
filter (>3) (map (\(x,y) -> x+y) xys)
3 (*). Generating Lists
Sometimes we want to generate lists of a certain length.
A. Write a generator
such that listOf n g generates a list of n elements, where each element is generated by g. What property would you write to test that your generator behaves as it should?listOfLength :: Integer -> Gen a -> Gen [a]
B. Now use
to write a generator that generates pairs of lists of the
same, random, length.
C.Take a look at the standard Haskell functions zip and unzip:
Write down two properties for these; one that says that zip is the inverse of unzip, and one that unzip is the inverse of zip. Note that unzip is not always the inverse of zip, so you need a condition! Could you make use of the generator you just defined?zip :: [a] -> [b] -> [(a,b)] unzip :: [(a,b)] -> ([a],[b])
Hint: make a datatype
and use your generator for part B. to make a generator for the above type. Then, make the above type an instance of Arbitrary. Finally, you can use it to write your property.data TwoSameLengthLists a = SameLength [a] [a]
Another possibility is to use the QuickCheck function
forAll, which we might see later on in the course.
4. Generating Ordered ListsWrite a generator that generates random lists of integers that are sorted (ordered), without using of the function sort! (And not of the generator
orderedListfrom the lecture either...)
Hint: First generate a list of random, positive integers. Then, generate a first, random number in the list. Then, produce a list where the differences between each consecutive pair of elements is given by the list of positive integers.
Make sure to check that your generator generates ordered lists by writing a suitable property!