====== L03. Higher-order functions ====== ===== Functions that take other functions as parameter ===== 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) ===== Functions that return other functions (curry functions) ===== 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) ===== Generalising and reusing code ===== /* 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))