-
Notifications
You must be signed in to change notification settings - Fork 328
/
Copy pathPartiallyAppliedFunctions.scala
82 lines (70 loc) · 2.67 KB
/
PartiallyAppliedFunctions.scala
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* scala-exercises - exercises-stdlib
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com>
*/
package stdlib
import org.scalatest._
/** @param name partially_applied_functions
*
*/
object PartiallyAppliedFunctions
extends FlatSpec
with Matchers
with org.scalaexercises.definitions.Section {
/** A partially applied function is a function that you do not apply any or all the arguments, creating another function. This partially applied function doesn't apply any arguments.
*/
def partiallyAppliedPartiallyAppliedFunctions(res0: Int, res1: Int) {
def sum(a: Int, b: Int, c: Int) = a + b + c
val sum3 = sum _
sum3(1, 9, 7) should be(res0)
sum(4, 5, 6) should be(res1)
}
/** Partially applied functions can replace any number of arguments:
*/
def anyNumberArgumentsPartiallyAppliedFunctions(res0: Int, res1: Int) {
def sum(a: Int, b: Int, c: Int) = a + b + c
val sumC = sum(1, 10, _: Int)
sumC(4) should be(res0)
sum(4, 5, 6) should be(res1)
}
/** Currying is a technique to transform a function with multiple parameters into multiple functions which each take one parameter:
*/
def curryingPartiallyAppliedFunctions(
res0: Boolean,
res1: Int,
res2: Int,
res3: Int,
res4: Int) {
def multiply(x: Int, y: Int) = x * y
(multiply _).isInstanceOf[Function2[_, _, _]] should be(res0)
val multiplyCurried = (multiply _).curried
multiply(4, 5) should be(res1)
multiplyCurried(3)(2) should be(res2)
val multiplyCurriedFour = multiplyCurried(4)
multiplyCurriedFour(2) should be(res3)
multiplyCurriedFour(4) should be(res4)
}
/**
* Currying also allows you to compose functions that have multiple parameter, since normally it's not possible:
*/
def curriedForComposition(res0: Int, res1: Int) {
def multiply(x: Int, y: Int) = x * y
val multiplyCurried = (multiply _).curried
def addOne(x: Int) = x + 1
val composedFunction = addOne _ compose multiplyCurried(2)
composedFunction(3) should be(res0)
val andThenComposedFunction = multiplyCurried(2) andThen addOne
andThenComposedFunction(4) should be(res1)
}
/** Currying allows you to create specialized versions of generalized functions:
*/
def specializedVersionPartiallyAppliedFunctions(res0: List[Int], res1: List[Int]) {
def customFilter(f: Int ⇒ Boolean)(xs: List[Int]) =
xs filter f
def onlyEven(x: Int) = x % 2 == 0
val xs = List(12, 11, 5, 20, 3, 13, 2)
customFilter(onlyEven)(xs) should be(res0)
val onlyEvenFilter = customFilter(onlyEven) _
onlyEvenFilter(xs) should be(res1)
}
}