Я хочу создать функцию сумма из карри и уменьшить, если у меня есть стандартные функции 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
.
Это можно обобщить, чтобы создать функцию из двух аргументов функции, которые можно вызывать с любыми аргументами, и уменьшить ее для каждого аргумента без использования встроенной функции.
Я хочу знать это, потому что я хочу узнать больше о программировании функций.