将函数列表传递给管道或在 Ramda.js 中组合
Pass a list of functions to pipe or compose in Ramda.js
关于接受多个参数的函数。
特别是我假设 "pipe" 和 "compose"。
他们将多个函数作为参数。
这时候我想给他们传一个多函数的列表
在Ramda.js
通常:
const piped = R.pipe(R.inc, R.negate);
我想要这样:
const funcs = [R.inc, R.negate];
const piped = R.pipe(funcs);
我也在考虑传递部分应用函数的列表
const funcs = [R.add (1), R.pow (2)];
这些列表中的函数没有名称 属性。
所以我想知道是否可以通过将这些 Ramdajs 函数和部分应用函数绑定到变量来找到解决方案。
但他们似乎并不那么聪明。
这是我第一次接触英语和堆栈溢出。
我很抱歉用丑陋的英语,因为它是机械翻译。
我该如何解决这个问题,请告诉我解决方案。
谢谢。
Ramda.js functions are normal javascript functions so Function.call
and Function.apply
方法可用。
所以你的问题的解决方案是使用 .apply
方法来应用多个参数(一个列表):
示例:
const funcs = [R.inc, R.negate];
const piped = R.pipe.apply(R, funcs);
还有一个 Ramda.apply
as well (which you can check in the Ramda documentation) but native Function.apply
method solves the problem elegantly and natively (note according to documentation of the pipe
function 没有提到使用特定上下文,因为 Ramda
文档中有一些其他功能)。
回复评论:
R.apply
与原生 apply
方法存在的绑定上下文问题完全相同(根据 Ramda documentation)。因此,apply
方法的上下文问题大多无关紧要。
您真正想要的是使用反向函数组合组合器(也称为逆变函子)折叠函数列表:
const inc = x => x + 1;
const sqr = x => x * x;
const reduce1 = f => xs =>
xs.reduce(f);
const contra = (g, f) => x =>
f(g(x));
console.log(
reduce1(contra) ([inc, inc, inc, sqr]) (1)); // 16
这仅适用于非空数组。我们需要一个带有累加器的折叠来使部分应用的折叠 reduce1(contra)
成为总函数:
const inc = x => x + 1;
const sqr = x => x * x;
const id = x => x;
const reduce = f => acc => xs =>
xs.reduce(f, acc);
const contra = (g, f) => x =>
f(g(x));
const pipen = reduce(contra) (id);
console.log(
pipen([inc, inc, inc, sqr]) (1)); // 16
console.log(
pipen([]) (1)); // 1
不过在 Ramda 中,使用 R.apply
完全没问题。但是注意这个函数是Ramda特有的。
将数组转换为多个参数的最简单方法是解构。在参数前加“...”:
const funcs = [R.inc, R.negate];
const piped = R.pipe(...funcs);
这里有更多关于解构的信息https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
关于接受多个参数的函数。
特别是我假设 "pipe" 和 "compose"。 他们将多个函数作为参数。
这时候我想给他们传一个多函数的列表
在Ramda.js 通常:
const piped = R.pipe(R.inc, R.negate);
我想要这样:
const funcs = [R.inc, R.negate];
const piped = R.pipe(funcs);
我也在考虑传递部分应用函数的列表
const funcs = [R.add (1), R.pow (2)];
这些列表中的函数没有名称 属性。 所以我想知道是否可以通过将这些 Ramdajs 函数和部分应用函数绑定到变量来找到解决方案。 但他们似乎并不那么聪明。
这是我第一次接触英语和堆栈溢出。 我很抱歉用丑陋的英语,因为它是机械翻译。 我该如何解决这个问题,请告诉我解决方案。 谢谢。
Ramda.js functions are normal javascript functions so Function.call
and Function.apply
方法可用。
所以你的问题的解决方案是使用 .apply
方法来应用多个参数(一个列表):
示例:
const funcs = [R.inc, R.negate];
const piped = R.pipe.apply(R, funcs);
还有一个 Ramda.apply
as well (which you can check in the Ramda documentation) but native Function.apply
method solves the problem elegantly and natively (note according to documentation of the pipe
function 没有提到使用特定上下文,因为 Ramda
文档中有一些其他功能)。
回复评论:
R.apply
与原生 apply
方法存在的绑定上下文问题完全相同(根据 Ramda documentation)。因此,apply
方法的上下文问题大多无关紧要。
您真正想要的是使用反向函数组合组合器(也称为逆变函子)折叠函数列表:
const inc = x => x + 1;
const sqr = x => x * x;
const reduce1 = f => xs =>
xs.reduce(f);
const contra = (g, f) => x =>
f(g(x));
console.log(
reduce1(contra) ([inc, inc, inc, sqr]) (1)); // 16
这仅适用于非空数组。我们需要一个带有累加器的折叠来使部分应用的折叠 reduce1(contra)
成为总函数:
const inc = x => x + 1;
const sqr = x => x * x;
const id = x => x;
const reduce = f => acc => xs =>
xs.reduce(f, acc);
const contra = (g, f) => x =>
f(g(x));
const pipen = reduce(contra) (id);
console.log(
pipen([inc, inc, inc, sqr]) (1)); // 16
console.log(
pipen([]) (1)); // 1
不过在 Ramda 中,使用 R.apply
完全没问题。但是注意这个函数是Ramda特有的。
将数组转换为多个参数的最简单方法是解构。在参数前加“...”:
const funcs = [R.inc, R.negate];
const piped = R.pipe(...funcs);
这里有更多关于解构的信息https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment