1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
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))
}
}
|