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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
/** A module defining utility methods for higher-order functional programming.
*
* @author Martin Odersky
* @version 1.0, 29/11/2006
*/
object Function {
/** Given a sequence of functions <code>f<sub>1</sub></code>, ...,
* <code>f<sub>n</sub></code>, return the function <code>f<sub>1</sub>
* andThen ... andThen f<sub>n</sub></code>.
*
* @param fs The given sequence of functions
* @return ...
*/
def chain[a](fs: Seq[a => a]): a => a = { x => (x /: fs) ((x, f) => f(x)) }
/** The constant function */
def const[T, U](x: T)(y: U): T = x
/** Turns a function `A => Option[B]` into a `PartialFunction[A, B]`. Important note:
* this transformation implies the original function will be called 2 or more
* times on each logical invocation, because the only way to supply an implementation
* of isDefinedAt is to call the function and examine the return value.
*
* @param f a function T => Option[R]
* @return a partial function defined for those inputs where
* f returns Some(_) and undefined where f returns None.
* @see PartialFunction#lift
*/
def unlift[T, R](f: T => Option[R]): PartialFunction[T, R] = new PartialFunction[T, R] {
def apply(x: T): R = f(x).get
def isDefinedAt(x: T): Boolean = f(x).isDefined
override def lift: T => Option[R] = f
}
/** Currying for functions of arity 2. This transforms a function
* of arity 2 into a a unary function returning another unary function.
*
* @param f ...
* @return ...
*/
@deprecated("Use `f.curried` instead")
def curried[a1, a2, b](f: (a1, a2) => b): a1 => a2 => b = {
x1 => x2 => f(x1, x2)
}
/** Currying for functions of arity 3.
*
* @param f ...
* @return ...
*/
@deprecated("Use `f.curried` instead")
def curried[a1, a2, a3, b](f: (a1, a2, a3) => b): a1 => a2 => a3 => b = {
x1 => x2 => x3 => f(x1, x2, x3)
}
/** Currying for functions of arity 4.
*/
@deprecated("Use `f.curried` instead")
def curried[a1, a2, a3, a4, b](f: (a1, a2, a3, a4) => b): a1 => a2 => a3 => a4 => b = {
x1 => x2 => x3 => x4 => f(x1, x2, x3, x4)
}
/** Currying for functions of arity 5.
*/
@deprecated("Use `f.curried` instead")
def curried[a1, a2, a3, a4, a5, b](f: (a1, a2, a3, a4, a5) => b): a1 => a2 => a3 => a4 => a5 => b = {
x1 => x2 => x3 => x4 => x5 => f(x1, x2, x3, x4, x5)
}
/** Uncurrying for functions of arity 2. This transforms a unary function
* returning another unary function into a function of arity 2.
*/
def uncurried[a1, a2, b](f: a1 => a2 => b): (a1, a2) => b = {
(x1, x2) => f(x1)(x2)
}
/** Uncurrying for functions of arity 3.
*/
def uncurried[a1, a2, a3, b](f: a1 => a2 => a3 => b): (a1, a2, a3) => b = {
(x1, x2, x3) => f(x1)(x2)(x3)
}
/** Uncurrying for functions of arity 4.
*/
def uncurried[a1, a2, a3, a4, b](f: a1 => a2 => a3 => a4 => b): (a1, a2, a3, a4) => b = {
(x1, x2, x3, x4) => f(x1)(x2)(x3)(x4)
}
/** Uncurrying for functions of arity 5.
*/
def uncurried[a1, a2, a3, a4, a5, b](f: a1 => a2 => a3 => a4 => a5 => b): (a1, a2, a3, a4, a5) => b = {
(x1, x2, x3, x4, x5) => f(x1)(x2)(x3)(x4)(x5)
}
/** Tupling for functions of arity 2. This transforms a function
* of arity 2 into a unary function that takes a pair of arguments.
*
* @note These functions are slotted for deprecation, but it is on
* hold pending superior type inference for tupling anonymous functions.
*
* @param f ...
* @return ...
*/
// @deprecated("Use `f.tupled` instead")
def tupled[a1, a2, b](f: (a1, a2) => b): Tuple2[a1, a2] => b = {
case Tuple2(x1, x2) => f(x1, x2)
}
/** Tupling for functions of arity 3. This transforms a function
* of arity 3 into a unary function that takes a triple of arguments.
*/
// @deprecated("Use `f.tupled` instead")
def tupled[a1, a2, a3, b](f: (a1, a2, a3) => b): Tuple3[a1, a2, a3] => b = {
case Tuple3(x1, x2, x3) => f(x1, x2, x3)
}
/** Tupling for functions of arity 4. This transforms a function
* of arity 4 into a unary function that takes a 4-tuple of arguments.
*/
// @deprecated("Use `f.tupled` instead")
def tupled[a1, a2, a3, a4, b](f: (a1, a2, a3, a4) => b): Tuple4[a1, a2, a3, a4] => b = {
case Tuple4(x1, x2, x3, x4) => f(x1, x2, x3, x4)
}
/** Tupling for functions of arity 5. This transforms a function
* of arity 5 into a unary function that takes a 5-tuple of arguments.
*/
// @deprecated("Use `f.tupled` instead")
def tupled[a1, a2, a3, a4, a5, b](f: (a1, a2, a3, a4, a5) => b): Tuple5[a1, a2, a3, a4, a5] => b = {
case Tuple5(x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5)
}
/** Un-tupling for functions of arity 2. This transforms a function taking
* a pair of arguments into a binary function which takes each argument separately.
*/
def untupled[a1, a2, b](f: Tuple2[a1, a2] => b): (a1, a2) => b = {
(x1, x2) => f(Tuple2(x1, x2))
}
/** Un-tupling for functions of arity 3. This transforms a function taking
* a triple of arguments into a ternary function which takes each argument separately.
*/
def untupled[a1, a2, a3, b](f: Tuple3[a1, a2, a3] => b): (a1, a2, a3) => b = {
(x1, x2, x3) => f(Tuple3(x1, x2, x3))
}
/** Un-tupling for functions of arity 4. This transforms a function taking
* a 4-tuple of arguments into a function of arity 4 which takes each argument separately.
*/
def untupled[a1, a2, a3, a4, b](f: Tuple4[a1, a2, a3, a4] => b): (a1, a2, a3, a4) => b = {
(x1, x2, x3, x4) => f(Tuple4(x1, x2, x3, x4))
}
/** Un-tupling for functions of arity 5. This transforms a function taking
* a 5-tuple of arguments into a function of arity 5 which takes each argument separately.
*/
def untupled[a1, a2, a3, a4, a5, b](f: Tuple5[a1, a2, a3, a4, a5] => b): (a1, a2, a3, a4, a5) => b = {
(x1, x2, x3, x4, x5) => f(Tuple5(x1, x2, x3, x4, x5))
}
}
|