Можно ли создать функцию суммирования приведения и карри без встроенных функций? - PullRequest
2 голосов
/ 21 апреля 2019

Я хочу создать функцию сумма из карри и уменьшить, если у меня есть стандартные функции apply и call:

Моя попытка:

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

Имеют ли такие функции, как caller и spread общее имя? Или есть лучший способ создать функцию суммы с этими требованиями? Я также могу использовать функции pipe или compose, потому что они также являются общими, не уверен, что вы можете использовать их для создания суммы.

Итак, в основном мой вопрос таков: возможно ли создать функцию суммы с использованием любой известной функции в функциональных библиотеках без каких-либо встроенных функций? Также возможны встроенные функции, такие как bind.

Это можно обобщить, чтобы создать функцию из двух аргументов функции, которые можно вызывать с любыми аргументами, и уменьшить ее для каждого аргумента без использования встроенной функции.

Я хочу знать это, потому что я хочу узнать больше о программировании функций.

...