1. (31 points) Suppose that the following definitions have been

1. (31 points) Suppose that the following definitions have been made:
x :: [Int]
x = [ w*10 | w <- [5 .. 10],
even w ]
u :: Int
u = 6
g, h :: Int -> [Int]
g i = [i]
h = g . (\ w -> w + 1)
test
test
test
test
:: [a] -> Int
(p:ps) = 1
(p:q:qs) = 2
_ = 3
(a) (19 pts) Give the values of the following expressions.
(i). x
Answer: [60, 80, 100]
(ii). [1, 5 .. 12]
Answer: [1,5,9]
(iii). ([u],"u")
Answer: ([6],"u")
(iv). [] : [[1,2], [3,4]]
Answer: [[], [1,2], [3,4]]
(v). map g [10, 15, 20]
Answer: [[10], [15], [20]]
(vi). h 6
Answer: [7]
(vii). test [20, 15, 10]
Answer: 1
(viii). test [[]]
Answer: 1
(ix). foldr (\e r -> 3*e + r) 1000 [1,10,100]
Answer: 1333
CIS 352
Exam 1
Name:
(b) (12 pts) Give the most general types of the following expressions.
(i). length .
g
Answer: Int -> Int
(ii). [u]++[]
Answer: [Int]
(iii). snd (x, h)
Answer: Int -> [Int]
(iv). map (\y -> [y]) x
Answer: [[Int]]
(v). map g
Answer: [Int] -> [[Int]]
(vi). [(h,u), (g,10)]
Answer: [(Int-> [Int], Int)]
2. (17 points)
(a) (3 pts) Give an example of a Haskell expression with type (Int -> Bool, Char).
Answer: (even, ’M’)
(b) (4 pts) Give a curried version of the following function, including its type declaration:
query :: ((Int -> Bool), Int) -> Bool
query (f, x) = f (n+1) && f (n-1)
Answer:
query :: (Int -> Bool) -> Int -> Bool
query f n = f (n+1) && f (n-1)
(c) (5 pts) Briefly explain the difference between a polymorphic function and an
overloaded function, and give an example of each.
Answer: A polymorphic function is a function that has multiple types and yet
has only a single definition: the function’s behavior is independent of the types
involved. For example, Haskell’s built-in length function is polymorphic. In
contrast, an overloaded function is a function that shares its name with other
defined functions: each definition/version of the function operates over a different
type. For example, Haskell’s built-in + and == operators are overloaded: the
implementation of + is different for integers and floating-point numbers.
(d) (5 pts) Is Haskell’s built-in function concat::[[a]] -> [a] higher-order ? Explain why or why not.
CIS 352
Exam 1
Name:
Answer: No. A higher-order function is a function that accepts functions as
arguments or returns a function as a result. The function concat accepts lists as
arguments and returns lists as results.
3. (12 points) Haskell has a built-in function
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
such that zipWith f xs ys uses the function f to combine corresponding elements of
xs and ys: the length of the resulting list is the length of the smaller of xs and ys.
For example, zipWith has the following behavior:
Main> zipWith (*) [1, 2, 3, 4] [100, 200, 300]
[100, 400, 900]
Main> zipWith (:) [1, 2, 3, 4] [[0,4], [5], [15], [3,1], [5,6]]
[[1,0,4], [2,5], [3,15], [4,3,1]]
Write your own version of zipWith that works as above.
Sample Answer:
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
zipWith _ _ _ = []
4. (15 points) Write a Haskell function
merge :: [[Int]] -> [Int]
such that merge lsts merges the lists in lsts (each assumed to be in ascending order)
to create a single list in ascending order. For example, your function should have the
following behavior:
Main> merge [[1,3,6],[2,13,15],[3,7],[20]]
[1,2,3,3,6,7,13,15,20]
Sample Answer:
merge = foldr merge2 []
where
merge2
:: [Int] -> [Int] -> [Int]
merge2 (x:xs) (y:ys)
| x < y
= x : merge2 xs (y:ys)
| otherwise = y : merge2 (x:xs) ys
merge2 [] ys = ys
merge2 xs [] = xs
CIS 352
Exam 1
Name:
5. (10 points) A zero of a function f is a value v such that f (v) is 0. For example, the
function g(x) = x + 3 has −3 as a zero, the function h(x) = x2 − 9 has two zeroes (3
and −3), and the function j(x) = |x| + 15 has no zeroes at all.
Write a Haskell function
zeroes :: (Int -> Int) -> Int -> [Int]
such that zeroes f limit returns a list containing all of the integer zeroes of the
function f between 0 and limit, inclusive. (If limit is less than 0, zeroes should
simply return the empty list.)
For example, the function should have the following behavior:
Main> zeroes (\ x -> x*x - 9) 5
[3]
Main> zeroes (\ x -> x*x - 9) 2
[]
Main> zeroes (\ x -> x*x - 6*x + 5) 10
[1,5]
Sample Answer:
zeroes f limit = [ x | x <- [0 .. limit], f x == 0]
6. (15 points) Matrices can be represented in Haskell by lists of lists: in particular, a
matrix with m rows and n columns can be represented by an m-element list of nelements lists. For example, the matrix
"
#
1 2
3 4
5 6
can be represented by the list [ [1, 2], [3, 4], [5, 6] ]. For this question, let’s
consider the special case where every element of the matrix is an integer. We can make
this representation explicit by introducing the following type synonym:
type Matrix = [[Int]]
The transpose of an m × n matrix M (written M T ) is the n × m matrix obtained
by reversing the role of rows and columns: that is, the ith row of M becomes the ith
column of M T . For example, the following two matrices are transposes of each other:


1 2
5
1
3
3 4 and
2 4 6
5 6
Write a Haskell function
CIS 352
Exam 1
Name:
transpose :: Matrix -> Matrix
that computes the transpose of its input. For example, your function should have the
following behavior:
Main> transpose [ [1, 2], [3, 4], [5, 6] ]
[[1,3,5],[2,4,6]]
You may assume that the input matrix is well formed (i.e., all of its rows have the same
number of columns) and that it contains at least one row and at least one column.
Sample Answer:
transpose ([]:rows) = []
transpose mat = (map head mat) : transpose (map tail mat)