Name: BU ID: CS 320 Midterm Exam Fall 2018 Write here the number of the problem you are skipping: You must complete 5 of the 6 problems on this exam for full credit. Each problem is of equal weight. Please leave blank, or draw an X through, or write Do Not Grade, on the problem you are eliminating; I will grade the first 5 I get to if I can not figure out your intention no exceptions! Use pen if possible, and try to avoid writing on the back of the page, but if you do so, please tell me! In composing your answers, remember that your goal is to show me you understand the techniques presented in the course; if you can not completely solve the problem, show me as much as you know and I will attempt to give you partial credit. Problem One (Types) Give the type for each of the following functions in the space indicated. Don t forget about class constraints if they are necessary. Use a, b, c, for type variables. (a) apply :: (a -> b) -> (c -> a) -> c -> b apply f g x = f (g x) (b) try :: Num a => a -> [a] -> [a] try x xs = x:(x+1):xs (c) mystery :: (a -> a) -> (a -> a -> a) -> a -> a -> a mystery f h x y = h (f (f x)) (h y y) (d) zipfunc :: Eq a => (a -> b) -> [a] -> [a] -> [(a, b)] zipfunc f xs ys = [ (x, f y) x <- xs, y <- ys, x /= y ]
Problem Two (Lambda Calculus) Consider the following lambda expression: (\f -> ( (\x -> f ((x x) x)) (\x -> f ((x x) x)) ) ) (z) Free! (a) Draw a line from each occurrence of a bound variable to the appropriate lambda binding. Circle any free variables and label as free. You don t have to recopy the expression, just draw on the formula as given above. (b) Give the first 2 reductions in the (infinite) sequence of reductions from this term, starting with the outermost reduction, i.e., the substitution of z for the bound variable f. (c) There is clearly a pattern here. What do you predict the term will look like after 100 reductions? Diagram this as best you can, using abbreviations---obviously you can t draw the whole thing--but convince me that you know what it will look like.
Problem Three (Let Expressions combined with Infinite Lists) In the following, a function try is defined in various ways using let expressions. For each of the following, indicate whether, in the context of that definition alone, typing (try 2) into the repl would: 1) produce a result (if so give it), 2) generate an error of some kind before even running, or 3) diverge by either running forever with no answer or trying to print out an infinite list. (a) try n = let (_,(x,y)) = ((2,3),(4,z)) (z:zs) = [1,2,3,4] (a:b:_) = [x+y,x*y,x-y] in (head zs) + a + b Solution: (1), it terminates with 11 (b) try n = let x = 3 y = x + (let n = 3 in x * n) in let n = n + 1 in n + y Solution: (3), this runs forever. (c) try n = let t = 1:[x*2 x <- t] f n = 1:[x*n x <- (f n)] in take (n+2) (f (head (tail t))) Solution: (1), it terminates with [1,2,4,8]
Problem Four (Haskell Programming) In this problem you will write a basic dictionary (map) in Haskell. The dictionary will be a list of pairs (key, value), where key and value can be arbitrary types (hence the functions you create below will be polymorphic), and where the list of pairs is sorted in ascending lexicographic order on the keys. For example, you might have the following: example :: [(Int,String)] example = [(2,"hi"), (5,"there"), (9,"folks")] (A) Write the function insert, which takes a key and a value and a dictionary, and returns a new dictionary where the pair (key,value) is now in the dictionary; if the key was already there, replace its value with the new value. Be SURE TO GIVE THE TYPE OF insert at the top of your solution. Be sure to maintain the list in ascending order of keys. (B) Write the function lookup, which takes a key and a dictionary, and if the key is in the dictionary, returns (Just value), and if not, returns Nothing. Be SURE TO GIVE THE TYPE OF lookup at the top of your solution. OR, more efficient, given the dictionary is ordered: (C) Write the function keys, which takes a dictionary and returns the list of all the keys in the table. Be SURE TO GIVE THE TYPE OF keys at the top of your solution.
Problem Five (Haskell Programming) (A) Recall that map takes a list and a function, and produces a new list by applying the function to every element of the list, having the type: map :: (a -> b)-> [a] -> [b] Implement map using the Haskell function foldr. (B) Recall that the Fibonacci numbers f0 = 1, f1 = 1, f2 = 2, f3 = 3, f4 = 5, f5 = 8 are defined by the rules f0 = f1 = 1 fn = fn-2 + fn-1 Write a definition of the infinite list of Fibonacci numbers in Haskell. Note carefully that we are NOT asking you to write a function to calculate the n th Fibonacci number, but to create an infinite list of all the Fibonacci numbers. You may use any of the standard Haskell functions. You may use list comprehensions or not, your choice. The trick here was to combine two parts of the sequence into one enumeration using zip!
Problem Six (Roll-Your-Own List Monads) Suppose you have written your own list type in Haskell, and you want to create a List Monad which behaves just as the normal one does, but using your own Lists. So for example, we should be able to do the following with our Lists, as with ordinary lists: pairs :: List a -> List b -> List (a,b) pairs xs ys = do x <- xs y <- ys return (x,y) Main> pairs (Cons 1 (Cons 2 Nil)) (Cons 3 (Cons 4 Nil)) Cons (1,3) (Cons (1,4) (Cons (2,3) (Cons (2,4) Nil))) Complete the following code template where indicated. Define any helper functions you want. import Prelude hiding ((++)) data List a = Nil Cons a (List a) deriving Show -- Just concatenation for our List type, might find this useful (++) :: List a -> List a -> List a (++) Nil ys = ys (++) (Cons x xs) ys = Cons x (xs ++ ys) instance Monad List where -- return :: a -> List a return x = Cons x Nil -- recall that (>>=) takes a List xs, applies f to each -- of its members and returns a list of all the results -- (>>=) :: List a -> (a -> List b) -> List b xs >>= f = collect xs f collect :: List a -> (a -> List b) -> List b collect Nil _ = Nil collect (Cons x xs) f = (f x) ++ (collect xs f)