barbiturat
5/23/2017 - 4:41 PM

accumulator

accumulator

const accumMaker = (pred, reducer, memo = 0) => (...args) => {
    const currentRes = reducer(...[memo, ...args]);
    return pred(currentRes) ? currentRes : (...nextArgs) => accumMaker(pred, reducer, currentRes)(...nextArgs)
};

// return itself until sum is lower than 10
const accumulator = accumMaker((val) => val >= 10, function (memo, ...args) {
    return [memo, ...args].reduce((previousValue, val) => previousValue + val, 0);
});
accumulator(5)(1)(7); // 13


//////// testing /////////////

let j = 0;

for (let i = 0, res = accumulator; i < 1000000; i++) {
    res = res(0);
    if (typeof res === 'function') {
        j++;
    }
}

setTimeout(() => console.log('j', j), 1);

//////// end of testing /////////////