不用内联函数就可以通过reduce和curry创建sum函数吗?

时间:2019-04-21 17:36:28

标签: javascript functional-programming sum reduce

如果要使用标准函数applycall,我想用咖喱创建函数求和并减少它:

我的尝试:

// 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));

是否可以使用以下方法创建求和函数:咖喱,应用,减少和/或调用?如果不能,则可以添加一些通用的已知函数,以允许在没有内联函数(包括箭头函数)的情况下创建和?

我可以创建如下求和函数:

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

所以看来我需要的是获取参数列表并将函数作为数组调用的函数。

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));

callerspread之类的函数是否有一些通用名称?还是有满足这些要求的更好的方法来创建求和函数?我也可以使用pipecompose函数,因为它们也很常见,不确定是否可以使用它们来创建和。

所以基本上我的问题是,可以使用函数库中的任何已知函数创建求和函数而无需任何内联函数吗?也允许使用bind之类的内置函数。

可以将其概括为从函数两个参数创建一个可以用任何参数调用的参数,并且可以在不使用内联函数的情况下减少每个参数。

我想知道这一点,因为我想进一步了解函数编程。

1 个答案:

答案 0 :(得分:1)

我不知道您所说的内联函数是什么意思。 但是:

function ad = (a, b) => a + b;

function sum (...args) {
  return args.reduce(add, 0);
}

console.log(sum(1, 2, 3, 4));

编辑:不明白原始问题,这是答案

// From lodash, is named differently in other FP libraries
const partialRight = (func, ...boundArgs) =>  (...remainingArgs) => 
func(...remainingArgs, ...boundArgs);

// From Lodash 
const rest = (fn) => (...args) => fn(args);

// From any FP library
const reduce = function(iterable, reduceFn, accumulator){
  for(let i of iterable){
    accumulator = reduceFn(accumulator, i)
  }
  return accumulator
}

const add = (a, b) => a + b;
const sum = rest(partialRight(reduce, add, 0));

console.log(sum(1, 2, 3, 4));