Implement redux compose function but get RangeError - javascript

I am trying to re-implement redux compose function, instead of using reduce i use a for loop, here is my code:
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
let result;
for (let i = funcs.length - 1; i > -1; i--) {
result = result
? (...args) => funcs[i](result(...args))
: (...args) => funcs[i](...args);
}
return result;
}
// test
function fn1(x) {
return x + 1;
}
function fn2(x) {
return x * 10;
}
function fn3(x) {
return x - 1;
}
console.log(compose(fn3, fn2, fn1)(10)); // 109
It is expected to log 109 since (10 + 1) * 10 - 1 is 109, however it gives me such error:
RangeError: Maximum call stack size
Looks like i am doing some recursion but all i did is just a for loop, no sure where is the problem of my code?

I think the issue is like the below example:
a = () => 2;
a = () => 3 * a();
console.log(a);
// this prints () => 3 * a() in console
// so when you call a(), it will call 3 * a(), which will again call 3 * a() and so on
// leading to infinite recursion
My solution is slightly different using bind function based on this reference link: https://stackoverflow.com/a/6772648/4688321.
I think bind creates a new copy of the function result and binds it to a new object. Not using bind leads to recursion because then the code becomes like the above example, result calls result.
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
let result;
for (let i = funcs.length - 1; i > -1; i--) {
if (i == funcs.length - 1)
result = (...args) => funcs[i](...args);
else {
let temp = result.bind({});
result = (...args) => funcs[i](temp(...args));
}
}
return result;
}
// test
function fn1(x) {
console.log("fn1");
return x + 1;
}
function fn2(x) {
console.log("fn2");
return x * 10;
}
function fn3(x) {
console.log("fn3");
return x - 1;
}
//console.log(compose(fn3, fn2, fn1));
let ret = compose(fn3, fn2, fn1);
console.log(ret(10)); // 109

Rather than trying to combine functions at the time of compose, it seems much easier to combine them at the time the resulting function is called:
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg
}
return function (...args) {
let result = funcs .at (-1) (...args)
for (let i = funcs.length - 2; i > -1; i--) {
result = funcs [i] (result)
}
return result
}
}
// test
function fn1(x) {
return x + 1;
}
function fn2(x) {
return x * 10;
}
function fn3(x) {
return x - 1;
}
console.log(compose(fn3, fn2, fn1)(10)); // 109
However, again, reduce make for a much cleaner implementation:
const compose = (...fns) => (arg) =>
fns .reduceRight ((a, fn) => fn (a), arg)
or if you want to allow the rightmost function to receive multiple variables, then
const compose = (...fns) => (...args) =>
fns .reduceRight ((a, fn) => [fn (...a)], args) [0]

Related

How to implement sum(1)(2)(3) === 6 [duplicate]

I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(1)(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Try this
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
Here's a more generic solution that would work for non-unary params as well:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
I hope this helped someone

javascript automatic memoization of function

I'm trying to implement memoization in javascript.
here's the code:
function memoize(func) {
var history = {}
var inner = function(n) {
if (n in history) {
return history[n];
}
let result = func(n)
history[n] = result;
return result;
}
return inner;
}
function fib(n) {
if (n <= 1) {
return n;
}
return fib(n-1) + fib(n-2)
}
/*
fib = memoize(fib);
console.log(fib(20)) // O(n)
*/
/*
fib2 = memoize(fib);
console.log(fib2(20)) // O(2^n)
*/
it works.. I can calculated values in O(n) but I lost the original function. any way to still have the original fib function accessible?
thanks
If you want to retain the original un-memoized version of fib you'll need to modify fib in some way, such as passing your recursive function as an argument. Otherwise, the recursive fib calls will remain as the un-memoized versions of your function.
eg:
function memoize(func) { // potentially update this to accept as hash function to calculate the key for `history` to make this more generic
var history = {}
var inner = function(n, ...args) {
if (n in history) {
return history[n];
}
let result = func(n, ...args);
history[n] = result;
return result;
}
return inner;
}
function fib(n, recursiveFn = fib) {
if (n <= 1) {
return n;
}
return recursiveFn(n - 1, recursiveFn) + recursiveFn(n - 2, recursiveFn)
}
const fastFib = memoize(fib);
console.log(fastFib(40, fastFib)); // O(n)
const slowFib = fib(40); // O(2^n)
console.log(slowFib);

creating a spy function using javascript

I am trying to build a spy function that will do this.
const func1 = function (x, y) {return x + y};
const func2 = spy(func1);
func2(2, 5) // => 7
func2(4, 5) // => 9
func2.calls() // => 2
func2.args() // => [[2, 5], [4, 5]]
I have created this function but I can seem to get the calls and args
function spy(func) {
let count = 0;
let allArgs = [];
function ispy() {
let args2 = Array.prototype.slice.call(arguments);
spy.calls = function() {
return count++;
}
spy.args = function() {
return allArgs.push(args2)
}
func.apply(this, args2);
}
return spy;
}
const func1 = function (x, y) {return x + y};
const func2 = spy(func1);
console.log(func2(2, 5))
console.log(func2.calls())
console.log(func2.args())
Please help me fix it and let me know what am I missing?
A few things,
You need to keep track of count and allArgs for every invocation of the spy call.
You need to return the result of the spied upon function from spy.
function spy(func) {
let count = 0;
let allArgs = [];
function spy() {
// increment count on every invocation
count++;
let args2 = Array.prototype.slice.call(arguments);
// shove arguments onto the allArgs array.
allArgs.push(args2);
spy.calls = function() {
return count;
}
spy.args = function() {
return allArgs;
}
//return the result;
return func.apply(this, args2);
}
return spy;
}
const func1 = function (x, y) {return x + y};
const func2 = spy(func1);
console.log(func2(2, 5))
console.log(func2.calls())
console.log(func2.args())
You add functions to spy in a call of ispy() and increment count in call of calls instead of call of ispy, you don't return result of func, you assign calls and args functions in every call to ispy and many other mistakes
function spy(func) {
let count = 0;
let allArgs = [];
function ispy(...args) {
count++;
allArgs.push(args);
return func.apply(this, args);
}
ispy.calls = function() {
return count;
}
ispy.args = function() {
return allArgs;
}
return ispy;
}
const func1 = function (x, y) {return x + y};
const func2 = spy(func1);
console.log(func2(2, 5));
console.log(func2(4, 5));
console.log(func2.calls())
console.log(func2.args())
You could take the arguments directly with rest parameters and return in the function only the value of the variables. The assignemnt should happen outside of the function, because if not it would require a call of func2 first.
Each call of ispy should be counted and the arguments should be added to.
function spy(func) {
function ispy(...args) {
count++;
allArgs.push(args);
return func.apply(this, args);
}
let count = 0;
let allArgs = [];
ispy.calls = () => count;
ispy.args = () => allArgs;
return ispy;
}
const func1 = function (x, y) {return x + y};
const func2 = spy(func1);
console.log(func2.calls())
console.log(func2(2, 5))
console.log(func2.calls())
console.log(func2.args())

Execute Multiple functions in a function

function executeActions(param)
{
if((param != undefined) && (param.length > 0))
{
for(i=0; i < param.length; i++)
{
//eval like function
param[i]();
}
}
}
function clearFields()
{
...
}
function showAbs(param)
{
if(param == 'insert')
{
...
}
else if(param == 'update')
{
...
}
else
{
...
}
}
$("#clearButton").click(function(event)
{
//var functions = ["clearFields()","showAbs('insert')"];
var a = showAbs('insert');
var functions = [clearFields, a];
executeActions(functions);
});
Hello everyone!
How can I execute some functions with parameters in a row in a set of instructions like i've showed above?
If they don't have any parameters, then the functions execute like in chain, but, if one or more of them uses
some parameters, it stops with the error: "param[i] is not a function".
Maybe if you have another elegant solution for this code, i'd appreciate if you share with us.
Thank you all in advance!
You can use partial application for this. Partial application means that you take a given function and fix one or more parameters to it. Example
function sum(a, b){
return a + b;
}
function product(a, b){
return a * b;
}
function doSomething(){
// do something
}
function runFunctions(funcs){
for(var i = 0;i<funcs.length;i++){
funcs[i]();
}
}
var mySum = function(){
return sum(5, 6);
}
var myProduct = function(){
return product(2, 3);
}
runFunctions(mySum, myProduct, doSomething);
The above is using ES 5 syntax. You could make this a bit more concise using ES 6 syntax:
const sum = (a, b) => a + b;
const product = (a, b) => a * b;
const doSomething = () => // do something
const runFunctions = funcs => {
for(func of funcs)
func();
}
var mySum = () => sum(5, 6);
var myProduct = () => product(2, 3);
runFunctions(mySum, myProduct, doSomething);
or you could use the bind function to take care of fixing the vars:
const sum = (a, b) => a + b;
const product = (a, b) => a * b;
const doSomething = () => // do something
const runFunctions = funcs => {
for(func of funcs)
func();
}
runFunctions(sum.bind(null, 5,6), myProduct.bind(null, 2,3), doSomething);
For me a way you want to achieve may be not readable for other developers.
You may create a function that will group all your function executions like:
function groupedFunctions{
return {
A: funcA(param),
B: funcB(param),
C: funcC(param)
}
}
function executeActions(funcObj, params) {
funcObj.A(params.a);
funcObj.B(params.b);
}
let params = {a: 1, b:2}
executeActions(groupedFunction(), params)

Currying a variadic function in JavaScript [duplicate]

I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(1)(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Try this
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
Here's a more generic solution that would work for non-unary params as well:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
I hope this helped someone

Categories