These are exercises about "higher order functions". 1.) Compute the result of each map. (a) map (fn x => x+3) [1, 3, 6, 5, 9] (b) map String.size ["cats", "dog", "apple", "pear"] (c) map length [[2,3,5], [4], [6,7,4,3], [4,4]] (d) map hd [[2,3,5], [4], [6,7,4,3], [4,4]] (e) map tl [[2,3,5], [4], [6,7,4,3], [4,4]] (f) map (map (fn x=>x+3)) [[2,3,5], [4], [6,7,4,3], [4,4]] (g) map (map (fn x=>x*x)) [[2,3,5], [4], [6,7,4,3], [4,4]] 2.) Let fun f x y z = 2*x + 3*y + 4*z; Describe each of the functions g1 through g14 (what formula does each function simplify to?). val g1 = f 5; fun g2 u v = f 5 u v; fun g3 u v = f 5 v u; fun g4 u v = f u 5 v; fun g5 u v = f u v 5; val g6 = f 5 4; fun g7 u = f 5 4 u; fun g8 u = f u 5 4; fun g9 u = f 5 u 4; val g10 = g2 5; val g11 = g3 5; val g12 = g4 5; val g13 = g5 5; fun g14 u v = g3 v u; 3.) Find the value of each of these expressions. (a) (fn x => 3*x+2) 5 (b) (fn x => (fn y => 3*x+y)) 5 2 (c) (fn x => x+2) ((fn x => 3*x) 5) (d) (fn x => (fn y => x (x y))) (fn w => 3*w) 4 (e) (fn x => (fn y => x*y)) ((fn w => 3*w) 4) 5 (f) (fn x => (fn y => fn z => z (x+y))) 3 4 (fn w => 5*w) (g) (fn f => fn g => fn x => f (g x)) (fn x => 5*x) (fn x => 6*x) 2 4.) Compute the result of each fold. (a) foldr (op +) 10 [1,2,3,4,5] (b) foldl (op +) 10 [1,2,3,4,5] (c) foldr (fn (x, y) => if (0 = x mod 2) then x+y else y) 0 [1,2,3,4,5,6] (d) foldr (fn (x, y) => (hd (explode x))::y) [] ["bye","saw","we","cat","dog"] (e) foldr (fn (f, xs) => map f xs) [2,3,4,5,6,7] [fn x=>2*x, fn x=>3*x, fn x=>x*x] For each of the exercises 5 through 9, use the map function to write one line of code that solves the problem. Your one line of code can use an anonymous lambda expression. 5.) Use map to write a one-line function maxPairs with type fn : (int*int) list -> int list where each item in the output list is the maximum of the two elements from the corresponding pair in the input list. fun maxPairs 6.) Use map to write a one-line function multPairs with type fn : (int*int) list -> int list where each item in the output list is the product of the two elements from the corresponding pair in the input list. fun multPairs 7.) Use map to write a one-line function incList with type fn : int -> int list -> int list that increments each element of the input list by an integer parameter. fun incList 8.) Use map to write a one-line function pairList with type fn : 'a list -> ('a * 'a) list that puts each element from the input list into a pair that duplicates that element. Here is an example. pairList [1,2,3,4] ==> [(1,1),(2,2),(3,3),(4,4)] fun pairList 9.) Use map to write a one-line function zeroNegs with type fn : int list -> int list that copies the numbers from the input list to the result list except that negative numbers should be replaced by 0. Here is an example. zeroNegs [2,~3,4,~5,~6,2,0,~1,8] ==> [2,0,4,0,0,2,0,0,8] fun zeroNegs For each of the exercises 10 through 16, use the foldr function to write one line of code that solves the problem. Your one line of code can use an anonymous lambda expression. 10.) Use foldr to write a one-line function dupList with type fn : 'a list -> 'a list that duplicates into the output list every item from the input list. So the length of the output list is twice the length of the input list. Here is an example. dupList [1,2,3,4] ==> [1,1,2,2,3,3,4,4] fun dupList 11.) Use foldr to write a one-line function trueCount with type fn : bool list -> int that consumes a list of boolean values and returns the number of true values in the input list. fun trueCount 12.) Use foldr to write a one-line function sumMaxs with type fn : (int * int) list -> int which consumes a list of pairs of integers and returns the sum of the maximum elements from each pair. Here is an example. sumMaxs [(1,2),(~1,1),(3,0),(4,4),(5,4)] ==> 15 fun sumMaxs 13.) Use foldr to write a one-line function max with type fn : int list -> int that returns the largest element in the non-empty input list. fun max 14.) Use foldr to write a one-line function member with type fn : ''a -> ''a list -> bool that returns true if and only if the first parameter is an element of the list parameter. fun member 15.) Use foldr to write a one-line function less with type fn : int -> int list -> int list that returns a list of all the elements from the input list that are less than the first input parameter. fun less 16.) Use foldr to write a one-line function addPairsPointwise with type fn : (int * int) list -> int * int that consumes a list of pairs of numbers and produces a pair of numbers where the first number in the output pair is the sum of all the first numbers from the input pairs and the second number in the output pair is the sum of all the second numbers from the input pairs. Here is an example. addPairsPointwise [(1,2),(3,4),(5,6),(7,8)] ==> (16,20) fun addPairsPointwise 17.) Write a recursive function indexPairs with type fn : 'a list -> (int * 'a) list that consumes a list and produces a list of pairs where every element from the input list is paired up with its index from the input list. Here are two examples. indexPairs (explode "hello") ==> [(0,'h'),(1,'e'),(2,'l'),(3,'l'),(4,'o')] indexPairs [5,5,5,5,5] ==> [(0,5),(1,5),(2,5),(3,5),(4,5)] Notice that this function consumes a list and produces another list the same length as the input list. Quite often this is a sign that the function can be written using the map function. Explain why indexPairs is NOT a good candidate for being implemented using map. Try to implement indexPairs using foldr or foldl. fun indexPairs 18.) (a) Write a function squarecube with type fn : int list -> (int * int) list that consumes a list of numbers and produces a list of pairs of numbers where the first number in a pair is the square of the corresponding input number, and the second number in a pair is the cube of the corresponding input number. Here is an example. squarecube [1,2,3,4] ==> [(1,1),(4,8),(9,27),(16,64)] fun squarecube (b) Write a function squarecube ' with type fn : (int * int) list -> (int * int) list that consumes a list of pairs of numbers and produces a list of pairs of numbers where the first number in an output pair is the square of the first number from the corresponding input pair, and the second number in an output pair is the cube of the second number from the corresponding input pair. Here is an example. squarecube' [(1,2),(2,3),(3,4)] ==> [(1,8),(4,27),(9,64)] fun squarecube' 19.) The result of evaluating this expression hd (tl (map map [fn x=>3+x,fn x=>3-x,fn x=>3*x])) [0,1,2,3] is the following list. [3,2,1,0] Explain why. 20.) Explain how ML evaluates the following expression. foldr (fn(h,xs)=>map h xs) [[2],[3],[4],[5],[6],[7]] (map map [fn x=>3+x,fn x=>3-x,fn x=>3*x]) 21.) Write a one line definition for the function zip3 with type fn : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list using zip, map, and a lambda expression. 22.) Each of the following functions consumes a list of numbers. Give a verbal description of what each function does. (Don't just read the definition of each function from left to right. Give an explanation of what the function does to an input list.) For this problem, give filter the following definition. fun filter p [] = [] | filter p (x::xs) = if p x then x::filter p xs else filter p xs; val f1 = (map (fn x => x*x)) o (map (fn y => Int.max (0, y))); val f2 = map ((fn x => x*x) o (fn y => Int.max (0, y))); val f3 = map ((fn x => x*x) o (fn y => Int.min (0, y))); val f4 = (map (fn x => x*x)) o (filter (fn y => 0 < y)); val f5 = (map (fn x => Int.max (~10, x))) o (map (fn y => Int.min ( 10, y))); val f6 = map ((fn x => Int.min (10, x)) o (fn y => Int.max (~10, y))); val f7 = filter (fn x => ~10 < x) o filter (fn y => y < 10); 23.) Figure out for yourself, and then verify, the types of the following expressions, if they have a type. If they do not have a type, explain why. For this problem, give fst the following definition. fun fst (a,b) = a; (a) map hd; (b) map o hd; (* o is the ML "composition" operator *) (c) hd o hd; (d) hd hd; (e) hd o map; (f) hd o (map hd); (g) hd o (map fst); (h) map fst; (i) map o fst; (j) fst o fst; (k) map (op +); 24.) Figure out for yourself, and then verify, the types of the following expressions, if they have a type. If they do not have a type, explain why. (a) fn x => x 5 (b) fn x => x x (c) fn x => x (d) fn x => 5 25.) Write a function that counts the number of upper case characters in a string.