L03. Higher-order functions

def sumWithf (f: Int => Int, start: Int, stop:Int): Int = {
  def aux(i: Int, acc: Int): Int =
    if (i>stop) acc
    else aux(i+1, f(i) + acc)
  aux(start,0)
}
sumWithf(x => x, 0, 10)
def withfp(f: Int => Int)(start: Int, stop: Int) : Int = {
  def aux(i: Int, acc: Int) : Int =
    if (i > stop) acc
    else aux(i+1, f(i) + acc)
  aux(start,0)
}
withfp(x => x)(0,10)
 
val sum: (Int, Int) => Int = withfp(x => x)
sum(0,10)
sum(10,20)
 
val squares: (Int, Int) => Int = withfp(x => x * x)
squares(1,5)
squares(4,5)
/* One final example
*  We can use higher-order functions to SEPARATE FUNCTIONALITY of our code.
*
*  Suppose we would like to find an interval [x, x + 10] such that the sum of
*  the range as a certain property (it is an even number).
*
*  We start with x = 0, we compute 0 + 1 + ... + 10 (then check if sum is even)
*  we repeat for x = 1, ....
*
*  A better (more general) is to SEPARATE the computation process, from the SEARCH process
*
*  The function reduce, will "reduce" an interval to a value
* */
 
def separation(reduce: (Int, Int) => Int) : Int = {
  def found(value: Int) : Boolean = value % 2 == 0 // the property that w need to check
 
  def search(x: Int) : Int = {
    val v = reduce(x,x+10)
    if (found(v)) x
    else search(x+1)
  }
  search(0)
}
 
separation(withfp(x => x))