Can somebody explain to me how Array.reduce can put functions as arguments in function composition like this:
const composeB = (f, g) => x => f(g(x))
const add = a => b => a + b
const add5 = add(5)
const double = a => a * 2
const add5ThenDouble = [double, add5].reduce(composeB)
console.log(add5ThenDouble(6)); // 22
So, according to my knowledge (which is not enough) of reduce function is that Array.reduce iterate through an array like this - it takes each of array values and puts them through callback function with another argument (lets call it accumulator). The next array value will undergo the same callback function, but with (eventually) changed accumulator value.
What confuses me in code example above is:
1) Array is list of functions [double, add5].
2) In first iteration, composeB will receive arguments: f=accumulator (empty value), g=double(function). ComposeB should return emptyvalue(double(6)) (or maybe not??)
I know that I am missing something, but can someone explain me what?
The documentation for reduce says that the first argument is
A function to execute on each element in the array (except for the first, if no initialValue is supplied).
So in this case, you have not supplied an initialValue
and so compose
is only called once (with arguments double
and add5
).
var inc = (x) => ++x, // increment +1
x2 = (x) => x*2, // multiply by 2
sq = (x) => x*x; // square
var compose = (f,g) => (_) => g(f(_));
var f1 = [ sq, inc, inc ].reduce(compose, (_) => _);
f1(10); // 102
var f2 = [ inc, sq, inc ].reduce(compose, (_) => _);
f2(10); // 122
See the code above, notice:
(_) => _
as default value (second argument) for reduce
f1
, only then the functions will be executed. [a,b,c,d,e]
into a chain of e,d,c,b,a
(reverse order!) and then execute as e(d(c(b(a(10)))))
getting the order we actually wanted.(f,g) => (_) => g(f(_))
<-- function arguments are actually reversed when calling them. Longer version: function compose (f, g) { return function (z) { return g(f(z)); }; }
function compose (f, g) { return function (z) { return g(f(z)); }; }
ps: i use var
because i can ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.