Lab 3. Higher-order functions
Objectives:
- implement and use higher-order functions. A higher-order function takes other functions as parameter or returns them
- implement curry and uncurry functions, and how they should be properly used (review lecture).
3.1. Define the function foldWith
which uses an operation op
, and an initial value b
to reduce a range of integers to a value. For instance, given that op
is addition (+), the result of folding the range 1 to 3 with b = 0
will be ( ( 0 + 1 ) + 2 + 3 = 6
. foldWith
should be curried (it will take the operation and return another function which expects the bounds).
def foldWith (b: Int)(op: (Int,Int) => Int)(start: Int, stop: Int): Int = { def tail_fold(crt: Int, acc: Int): Int = ??? ?? }
3.2. Define the function foldConditional
which extends foldWith
by also adding a predicate p: Int ⇒ Int
. foldConditional
will reduce only those elements of a range which satisfy the predicate.
def foldConditional(b: Int)(op: (Int,Int) => Int, p: Int => Boolean)(start: Int, stop: Int): Int = ???
3.3. Implement the function foldRight
which has the same behaviour as foldWith
, but the order in which the operation is performed is now: 1+(2+(3+0))=6
. What is the simplest way to implement it?
3.4. Write a function foldMap
which takes values $ a_1, a_2, \ldots, a_k$ from a range and computes $ f(a_1)\;op\;f(a_2)\;op\;\ldots f(a_k)$ .
def foldMap(op: (Int,Int) => Int, f: Int => Int)(start: Int, stop: Int): Int = ???
3.5. Write a function which computes $ 1 + 2^2 + 3^2 + \ldots + (n-1)^2 + n^2$ using foldMap
.
def sumSquares(n: Int): Int = ???
3.6. Write a function hasDivisor
which checks if a range contains a multiple of k. Use foldMap
and choose f
carefully.
def hasDivisor(k: Int, start: Int, stop: Int): Boolean = ???
3.7. We can compute the sum of an area defined by a function within a range a,b (the integral of that function given the range), using the following recursive scheme:
- if the range is small enough, we treat f as a line (and the area as a trapeze). It's area is $ (f(a) + f(b))(b-a)/2$ .
- otherwise, we compute the mid of the range, we recursively compute the integral from a to mid and from mid to b, and add-up the result.
Implement the function integrate
which computes the integral of a function f given a range:
def integrate(f: Double => Double)(start: Double, stop: Double): Double = ???
3.8. We define Line2D
to be lines in a 2-dimensional space, and we represent them as functions. Write a function which takes a Line2D and translates it up on the Ox axis by a given offset. For instance, translateOx of 2 on y=x+1 will return y=x+3.
type Line2D = Int => Int def translateOx(offset: Int)(l: Line2D): Line2D = ???
3.9. (!) Write a function which takes a Line2D and translates it up on the Oy axis by a given offset.
def translateOy(offset: Int)(l: Line2D): Line2D = ???
3.10. Write a function which takes two lines, and checks if there exist integer coordinates within a given range for x, where the lines intersect.
def intersect(l1: Line2D, l2: Line2D)(start: Int, stop: Int): Boolean = ???
3.11. Write a function which takes two lines and a range of integers, and checks if l1 has larger y values than l2 over the entire range.
def larger(l1: Line2D, l2: Line2D)(start: Int, stop: Int): Boolean = ???