I want to create function sum out of curry and reduce if I have standard functions apply and call:

My try:

// those are init functions:

function type(label, arg, type) {
  // some type checking so you know which function
  // throw exception and why
  var arg_type;
  if (arg instanceof Array) {
     arg_type = 'array';
  } else if (arg === null) {
     arg_type = 'null';
  } else {
     arg_type = typeof arg;
  }
  if (arg_type !== type) {
    throw new Error(`${label}: Expecting ${type} got ${arg_type}`);
  }
}


function curry(fn, ...init_args) {
    type('curry', fn, 'function');
    var len = fn.length;
    return function() {
        var args = init_args.slice();
        function call(...more_args) {
            args = args.concat(more_args);
            //console.log({fn, len, args});
            if (args.length >= len) {
                return fn.apply(this, args);
            } else {
                return call;
            }
        }
        return call.apply(this, arguments);
    };
}
function reduce(fn, init, ...lists) {
    if (lists.some(l => !l.length)) {
        return init;
    }
    type('reduce', fn, 'function');
    lists.forEach(a => type('reduce', a, 'array'));
    const head = lists.map(l => l[0]);
    const rest = lists.map(l => l.slice(1));
    return reduce(fn, fn(...head, init), ...rest);
}
function apply(fn, args) {
   type('apply', fn, 'function');
   type('apply', args, 'array');
   return fn.apply(null, args);
}
function call(fn, ...args) {
    type('call', fn, 'function');
    return fn.call(null, ...args);
}
var add = (a, b) => a + b;

// and this only using those without new inline function
var sum = curry(call, curry(reduce, add));
console.log(sum(1, 2, 3, 4));
var sum = curry(apply, curry(reduce, add));
console.log(sum(1, 2, 3, 4));

Is it possible to create sum function with: curry, apply, reduce and/or call? If not is it possible to add some generic known function that will allow to create sum without inline functions (this include arrow functions)?

I can create sum functions like this:

var sum = (...args) => reduce(add, 0, args);

so it seems what I need is function that get list of arguments and call function as array.

function caller(fn, ...args) {
   return fn.call(null, args);
}
var sum = curry(caller, curry(reduce, add, 0));
console.log(curry(reduce, add, 0)([1,2,3,4]));
console.log(sum(1, 2, 3, 4));

function spread(fn) {
    return function(...args) {
        return call(fn, args);
    };
}

var sum = spread(curry(reduce, add, 0));
console.log(sum(1, 2, 3, 4));

Does functions like caller and spread have some common name? Or is there a better way to create sum function, with those requirement? I can also use pipe or compose functions because they are also common, not sure if you can use them to create sum.

So basically my question is this, is possible to create sum function using any known function in functional libraries without any inline functions? Builtin functions like bind are also allowed.

This can be generalized to create a function from function two arguments that can be called with any arguments and it reduce on each argument without using inline function.

I want to know this because I want to know more about function programming.

0 Answers