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)
© Copyright 2026 Paperzz