-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpipe.js
110 lines (78 loc) · 2.95 KB
/
pipe.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
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
// We're going to create our own pipe function!
// Some basic functions for easily understand the pipe function.
// We'll combine those three function and send the value 4 to it.
// Getting result of - 'Numner 10'
const add1 = x => x + 1;
const mul2 = x => x * 2;
const title = x => `The number is: ${x}`;
// The most imperative and naive way of writing the pipe function
// Calling the function with:
// pipe1([add1, mul2, title])
function pipe1 (array_of_fn) {
return function(x) {
let result = x;
for (let i = 0; i < array_of_fn.length; i++) {
let func = array_of_fn[i];
result = func(result)
}
return result;
}
}
x = pipe1([add1, mul2, title])(4); // 'The number is: 10'
// let's use the rest operator
// So no, calling the function will be with no array:
// pipe1(add1, mul2, title)
function pipe2 (...funcs) {
return function(x) {
let result = x;
for (let func of funcs) {
result = func(result)
}
return result;
}
}
x = pipe2(add1, mul2, title)(4); // 'The number is: 10'
// Now, let's forget all about the "for" loop and use the reduce.
// For using the reduce we must have an initial value (like we had in Sum and Mul)
// We'll use the identity function which is:
function identiy(x) {
return x;
}
// or
const identity = x => x;
// This version is super verbose for understanding what's going on
// The function pipeTwoFunctions gets two functions, and return a new function.
function pipe3 (...funcs) {
const pipeTwoFunctions = function(first, second) {
return function(x) {
return second(first(x))
}
}
const result = funcs.reduce(pipeTwoFunctions, identity)
return result;
}
// Minimize the pipeTwoFunctions function by using the fat arrow operator
// Now try to understand why we have two fat arrows in the function.
function pipe4 (...funcs) {
const pipeTwoFunctions = (first, second) => x => second(first(x));
const result = funcs.reduce(pipeTwoFunctions, identity)
return result;
}
// declare the pipeTwoFunctions inside the reduce function.
function pipe5 (...funcs) {
return funcs.reduce((acc,curr) => x => curr(acc(x)) , identity);
}
// Change to an arrow function for awoesmness
const pipe6 = (...funcs) => funcs.reduce((acc,curr) => x => curr(acc(x)) , identity);
// =======================================================
// final result
// =======================================================
// Dealing with more than one argument in the first function,
// by sending the first function as the initiator for the reduce function.
// We also using the arguments object here, because we don't know the how many argument
// was passed
const pipe = (first, ...more) =>
more.reduce((acc,curr) => (...arguments) => curr(acc(...arguments)) , first);
// Two arguments function-
const div = (x,y) => x / y;
x = pipe(div, add1, mul2, title)(4,2); // 'The number is: 6'