This is an old revision of the document!


Higher-order functions

Function application and composition as higher-order functions

One key idea from functional programming is that functions are first-class (or first-order) values, just like integers, strings, etc. . They can be passed as function arguments and also be returned by function application.

Functions which take other functions as parameter are called higher-order. We have already encountered two such functions, i.e. ($) and (.).

43. Define the operator ($) from Lab 2 as a higher-order function.

44. What type should functional composition have?

45. Define function composition.

46. Functions can be passed as arguments just like any other value value. Also, functions can be returned as parameter. In order to do so, it is convenient to define functions without naming them. This is than using lambda's. For a more detailed discussion regarding lambdas, see the lecture. The following definitions are equivalent:

f x y = x + y 
f x = \y -> x + y
f = \x -> \y -> x + y
f = \x y -> x + y

That is the type of f? What is the type of f 5?

47. Consider sets represented as characteristic functions with signature

   s :: Integer -> Bool
   s x is true if x is in the set.
  Write a membership function
 mem s x = s x
 or 
 mem = ($)

48. Write the set {1,2,3}

 f 1 = True
 f 2 = True
 f 3 = True
 f _ = False

49. Write the set of natural numbers

 f x = x > -1

50. Implement the intersection of two sets:

union f g = \x → f x && g x

51. Write reunion in another way

union f g x = f x && g x

52. Write a function which takes a list of sets, and returns that set

53. (hard) Implement a function which takes a list of sets and computes their intersection

f [s] = s f (s:xs) = \x → s x && (f xs) x

54. Write a function which receives a g :: Integer → Bool, a list of integers,

  and returns a list of integers for which g is true.

filter p [] = [] filter p (x:xs)

| p x == True = x:(filter p xs)
| otherwise = filter p xs

55. Solve exercise 22. using filter

f = filter (>0)

56. Implement map

57. Solve exercise 15. using map:

f = map g

	where g True = 1
	      g False = 0

58. Solve exercise 25. using map and filter: Let f “321CB” [(“321CB”, [“Matei”, “Andrei”, “Mihai”]), (“322CB”,[“George, Matei”])]

= ["Matei", "Mihai"]
(Hint. Pattern matching can be used in lambdas. Use fst and snd on pairs)

f x l = (filter (\(c:_)→ c == 'M')) $ snd $ head $ (filter (\(f,_)→ f==x)) l

or

f x = (filter (\(c:_)→ c == 'M')) . snd . head . (filter (\(f,_)→ f==x))

59. Solve exercise 29. using map and filter

  f [("Dan Matei Popovici",9),("Mihai",4),("Andrei Alex",6)] =
  	[(["Dan", "Matei", "Popovici"],10),(["Andrei,Alex"],6)]

f = bonus . splall . rem

where
	rem = filter (\(_,y) -> y > 4)
	splall = map (\(x,y) -> (spl x,y))
	bonus = map (\(l,y) -> if length l == 3 then (l,y+1) else (l,y))
	spl [] [] rest = rest

spl [] w rest = w:rest spl (x:xs) w rest | x == ' ' = spl xs [] (w:rest) | otherwise = spl xs (x:w) rest

60. Write a function which appends a list of lists:

f [] = [] f (x:xs) = x ++ (f xs)

61. Write the same function tail-recursively

f [] acc = acc f (x:xs) acc = f xs (x++acc)

Are the two functions identical? Why?

62. Implement foldr

63. Implement foldl

64. Implement concatenation using a fold:

app l1 l2 = foldr (:) l2 l1

65. Implement reversal using a fold:

rev = foldl (\x y->y:x) []

66.(hard) Implement the string-splitting function from exercise 46 using folds:

  (Hint: thing about what the accumulator should hold)

(Note for TA: signature needed. Discussion for later)

spl :: String → [String] spl = foldr op [“”]

      where op ' ' (l:rest) = []:l:rest
            op c (l:rest) = (c:l):rest
		  

67. Implement exercise 47 using fold:

f (s:xs) = foldr (\s acc x→ s x && acc x) s xs