-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdigression.js
64 lines (49 loc) · 1.54 KB
/
digression.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
/*
.map is great, because we can
chain tiny operations together to describe
a complex transformation on a collection,
using only tiny blocks
*/
const increment = x => x + 1;
const triple = x => x * 3;
const halve = x => x / 2;
[1, 2, 3]
.map(increment)
.map(triple)
.map(halve); // [3, 4.5, 6]
/*
if given 1,000,000 numbers, the above example
would run 3,000,000 operations.
Luckily, we can `compose` all of the `map` operations together,
into 1 map.
*/
// this isn't important; it's here for completion
const compose = (...functions) =>
functions.reduce((thenRunThis, runThis) => (input) =>
thenRunThis(runThis(input)), (x) => x);
[1, 2, 3].map(x => halve(triple(increment(x))));
// OR
[1, 2, 3].map(compose(halve, triple, increment));
/* ASIDE:
While we don't often think about it in the same way,
we can compose `.filter` using AND, and we can compose
sub-sorting over OR; technically `compose` is composing over
`apply`ing functions to a value, in order
*/
/* Transducing is `compose`, but for reducers.
It's a way of chaining reducers together,
to operate one after another, inside of one reduce method.
But we CAN'T compose `.reduce` the same way.
Reduce takes 2 arguments (that we care about)
and returns 1 value;
we can't give reduce 2 values based on 1 value.
So let's try from another angle.
*/
/* Challenge:
instead of using `.map`, rewrite the following using `.reduce`
*/
[1, 2, 3].map(increment); // [2, 3, 4]
[1, 2, 3].reduce(/* ... */); // [2, 3, 4]
/* Hint:
see transducer.js
*/