Let's take a look at your compose1
by breaking it down:
const compose1 = (...fns) => {
// Returns a function that reduces fns each time it is called
return (...args) => {
// Returns the reduction of fns
return fns.reduce((f,g) => {
// Returns the result of calling f(g(...args))
return f(g(...args))
})
}
};
Now lets go through a sample call of this version of compose:
compose1(add(6), multi(4), devide(5))(5);
First, we call compose1
. This returns this function:
(...args) => {
// Returns the reduction of fns
return fns.reduce((f,g) => {
// Returns the result of calling f(g(...args))
return f(g(...args))
})
}
We then call this function with a parameter of 5
, which is essentially calling fns.reduce
as in the previously returned function. To see what exactly is going wrong, let's run through a few iterations of the reduce:
First iteration:
fns.reduce((f = add(6), g = multi(4)) => {
// Returns the result of calling f(g(...args))
return f(g(...args = [5]))
// g is `multi(4)`, so do `multi(4)(5)`, which returns 20. Next:
// f is `add(6)`, so do `add(6)(20)`, which returns 26.
// Remember that the return from last iteration is
// the first parameter of the next iteration
})
Second iteration:
fns.reduce((f = 26, g = devide(5)) => {
// Returns the result of calling f(g(...args))
return f(g(...args = [5]))
// g is `devide(5)`, so do `devide(5)(5)`, which returns 1. Next:
// f is 26, so do `26(1)`. However, 26 is not a function.
// You get the error `f is not a function`.
})