object Curry { // high order function def sum(f: Int => Int, a: Int, b: Int) = { def loop(a: Int, acc: Int): Int = if (a > b) acc else loop(a + 1, f(a) + acc) loop(a, 0) } // curry version: this function return an (Int, Int) => Int function def sumCurry(f: Int => Int): (Int, Int) => Int = { def sumF(a: Int, b: Int): Int = if (a > b) 0 else f(a) + sumF(a + 1, b) sumF } def cube (x: Int): Int = x * x * x def sumInts = sumCurry(x => x) def sumCubes = sumCurry(x => x * x * x) // syntax shortcut def sumCurryShort(f: Int => Int)(a: Int, b: Int): Int = if (a > b) 0 else f(a) + sumCurryShort(f)(a + 1, b) // add _ if you want to treat it as a partially applied function def sumCubesShort = sumCurryShort(cube)_ // product def product(f: Int => Int)(a: Int, b: Int): Int = if (a > b) 1 else f(a) * product(f)(a + 1, b) def fact(n: Int) = product(x => x)(1, n) // add unit value and combining function => sum and product generalisation def mapReduce(f: Int => Int, c: (Int, Int) => Int, u: Int )(a: Int, b: Int): Int = if (a > b) u else c(f(a), mapReduce(f, c, u)(a + 1, b)) def run = { println("Curry") println(sum(x => x * x, 3, 5)) println(sumInts(3, 5)) println(sumCurry(cube)(3, 5)) println(sumCubes(3, 5)) println(sumCurryShort(cube)(3, 5)) println(sumCubesShort(3, 5)) println(product(x => x * x)(3, 4)) println(fact(4)) println(mapReduce(x => x * x, (x, y)=> x + y, 0)(3, 5)) println(mapReduce(x => x * x, (x, y)=> x * y, 1)(3, 4)) } }