-
Notifications
You must be signed in to change notification settings - Fork 0
/
fnx.js
71 lines (64 loc) · 2.03 KB
/
fnx.js
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
(function (global) {
var slice = Array.prototype.slice;
/**
* Partially apply the specified function by returning a new function that
* associates specified arguments to be used as the leading arguments at the
* time of execution.
*
* Example:
*
* function buildChineseName(lastName, firstName, middleName) {
* return lastName + ' ' + firstName + '-' + middleName;
* }
*
* var buildLiFamilyName = partial(buildChineseName, 'Li');
*
* buildLiFamilyName('Qi', 'Xian'); // returns 'Li Qi-Xian';
*/
function partial(fn) {
/**
* Remember the n arguments specified after the function to be partially
* applied: these will be the first n arguments used when the returned
* function is executed.
*/
var partiallyAppliedArguments = slice.call(arguments, 1);
/**
* This new function will apply the specified function `fn` to the
* combination of the partially applied arguments and any arguments that
* are provided at execution time.
*/
return function () {
var completeArguments = partiallyAppliedArguments.concat(slice.call(arguments));
return fn.apply(this, completeArguments);
};
}
/**
* Set up a pipeline of the specified functions such that the return value
* of one function acts as the argument for the next one. Note that the
* functions are executed in the reverse order in which they are provided as
* arguments which aligns with the mathematical concept of functional
* composition: the composition of functions f1, f2 and f3 is the expression
* f1(f2(f3(x))).
*/
function compose() {
var functions = arguments;
var steps = functions.length;
return function () {
var value = arguments;
var n = steps;
/**
* Apply the functions in reverse order, storing the return value
* of each application into an array to be used as the argument for
* the next application.
*/
while (--n >= 0) {
value = [functions[n].apply(this, value)];
}
return value[0];
};
}
global.fnx = {
compose: compose,
partial: partial
};
})(this);