如何将 R.pipe 与多个参数一起使用?
How to use R.pipe with multiple arguments?
背景
我正在学习 Ramda,我正在尝试使用 pipe
。为此,我做了这个不起作用的简单示例:
var getSQLQuery = ( { lang } ) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
var comp = ( country, queryParams ) => R.pipe(
getSQLQuery( queryParams ),
addAnd,
getMarket( country ),
R.tap( console.log )
)(country, queryParams);
comp("Spain", {lang: "uk"}); //Blows Up!?
我得到的错误是
First argument to _arity must be a non-negative integer no greater
than ten
我不知道如何解决这个问题。我该怎么做?
这是否使代码比仅使用单个函数更具可读性是有争议的,但通过这种方式您可以获得所需的内容:
var getSQLQuery = (_, {lang}) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
var comp = ( country, queryParams ) => R.pipe(
getSQLQuery,
addAnd,
getMarket( country ),
R.tap( console.log )
)(country, queryParams);
comp("Spain", {lang: "uk"});
在回答核心问题 "how to use x with multiple arguments" 时,从技术上讲,您可以使用 R.nthArg,但这并不能立即帮助您通过管道传递数据。
在我看来,最好传入一个数组 - 或者使用剩余参数。这有效:
//Kept as original
var getSQLQuery = ( { lang } ) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
//only modified this function
const comp = (...args) =>
getMarket(args[0]) (
R.compose(addAnd, getSQLQuery)(args[1])
);
comp("Spain", {lang: "uk"});
虽然我不认为 R.compose
真的让推理变得更容易。也许如果它像这样被分离成一个命名函数?
const enhanceQuery = R.compose(addAnd, getSQLQuery)
const comp = (...args) =>
getMarket(args[0]) (enhanceQuery(args[1]));
编写这样一个函数的方法有很多种。我知道你的目标是学习如何使用 pipe
,但让我先展示一个与你的函数类似的技术:
const getSQLQuery = ( { lang } ) => `My query is ${lang}`;
const getMarket = country => `my country is ${country}`;
const flipAndJoin = pipe(reverse, join(' and '))
const comp = useWith(unapply(flipAndJoin), [getMarket, getSQLQuery])
comp("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
现在的问题是:
- 为什么你的功能不起作用?
- 如何让它发挥作用?
- 如何让
pipe
按预期工作?
为什么你的功能不起作用?
很简单:pipe
将多个函数作为参数,至少需要一个函数。您提供的第一个参数是 getSQLQuery( queryParams )
,这是使用参数调用 getSQLQuery
的 结果 。那是一个字符串,而不是一个函数。因此,当您尝试将其包装在 pipe
中时,它会失败。 (关于 'arity' 的注释与 Ramda 的内部结构有关:它使用第一个函数 pipe
来确定结果函数应该采用多少参数。)
如何让它发挥作用?
我在上面给出了答案。 MarioF 的回答对您的初始功能进行了最小的更改。
但是其中 none 和
一样简单
const comp2 = (country, queryParams) =>
`My query is ${queryParams.lang} and my country is ${country}`
comp2("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
如何让 pipe
按预期工作?
您需要了解 pipe
的作用。
想像这样的函数:
const getUpperAddr(userName, collection) {
const configStr = getUserConfig(userName, collection);
const config = JSON.parse(configStr);
const address = prop('address')(config);
const addrLine1 = prop('addrLine1')(address);
const upperAddr = toUpper(addrLine1);
return upperAddr;
}
忘记细节,尤其是 getUserConfig
是如何工作的,忘记任何潜在的错误,我们可以看到这个函数的一个有趣的特征:每个连续的局部变量都是通过将一个函数应用于前一个函数来创建的。唯一的例外是第一个,它使用函数的参数。结果是最终的局部变量。
pipe
只是一种使它更具声明性的方法,并消除了对所有局部变量(甚至参数名称)的需要。这等价于:
const getUpperAddr = pipe(
getUserConfig,
JSON.parse,
prop('address'),
prop('addrLine1'),
toUpper
);
这与上面的签名相同,returns相同输入的相同结果。如果你能用第一种格式写你的函数,你可以机械地改成pipe
。过了一会儿,这就变成了第二天性,你可以跳过第一步。
背景
我正在学习 Ramda,我正在尝试使用 pipe
。为此,我做了这个不起作用的简单示例:
var getSQLQuery = ( { lang } ) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
var comp = ( country, queryParams ) => R.pipe(
getSQLQuery( queryParams ),
addAnd,
getMarket( country ),
R.tap( console.log )
)(country, queryParams);
comp("Spain", {lang: "uk"}); //Blows Up!?
我得到的错误是
First argument to _arity must be a non-negative integer no greater than ten
我不知道如何解决这个问题。我该怎么做?
这是否使代码比仅使用单个函数更具可读性是有争议的,但通过这种方式您可以获得所需的内容:
var getSQLQuery = (_, {lang}) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
var comp = ( country, queryParams ) => R.pipe(
getSQLQuery,
addAnd,
getMarket( country ),
R.tap( console.log )
)(country, queryParams);
comp("Spain", {lang: "uk"});
在回答核心问题 "how to use x with multiple arguments" 时,从技术上讲,您可以使用 R.nthArg,但这并不能立即帮助您通过管道传递数据。
在我看来,最好传入一个数组 - 或者使用剩余参数。这有效:
//Kept as original
var getSQLQuery = ( { lang } ) => `My query is ${lang}`;
var addAnd = str => str + " and";
var getMarket = country => data => `${data} my country is ${country}`;
//only modified this function
const comp = (...args) =>
getMarket(args[0]) (
R.compose(addAnd, getSQLQuery)(args[1])
);
comp("Spain", {lang: "uk"});
虽然我不认为 R.compose
真的让推理变得更容易。也许如果它像这样被分离成一个命名函数?
const enhanceQuery = R.compose(addAnd, getSQLQuery)
const comp = (...args) =>
getMarket(args[0]) (enhanceQuery(args[1]));
编写这样一个函数的方法有很多种。我知道你的目标是学习如何使用 pipe
,但让我先展示一个与你的函数类似的技术:
const getSQLQuery = ( { lang } ) => `My query is ${lang}`;
const getMarket = country => `my country is ${country}`;
const flipAndJoin = pipe(reverse, join(' and '))
const comp = useWith(unapply(flipAndJoin), [getMarket, getSQLQuery])
comp("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
现在的问题是:
- 为什么你的功能不起作用?
- 如何让它发挥作用?
- 如何让
pipe
按预期工作?
为什么你的功能不起作用?
很简单:pipe
将多个函数作为参数,至少需要一个函数。您提供的第一个参数是 getSQLQuery( queryParams )
,这是使用参数调用 getSQLQuery
的 结果 。那是一个字符串,而不是一个函数。因此,当您尝试将其包装在 pipe
中时,它会失败。 (关于 'arity' 的注释与 Ramda 的内部结构有关:它使用第一个函数 pipe
来确定结果函数应该采用多少参数。)
如何让它发挥作用?
我在上面给出了答案。 MarioF 的回答对您的初始功能进行了最小的更改。
但是其中 none 和
一样简单const comp2 = (country, queryParams) =>
`My query is ${queryParams.lang} and my country is ${country}`
comp2("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
如何让 pipe
按预期工作?
您需要了解 pipe
的作用。
想像这样的函数:
const getUpperAddr(userName, collection) {
const configStr = getUserConfig(userName, collection);
const config = JSON.parse(configStr);
const address = prop('address')(config);
const addrLine1 = prop('addrLine1')(address);
const upperAddr = toUpper(addrLine1);
return upperAddr;
}
忘记细节,尤其是 getUserConfig
是如何工作的,忘记任何潜在的错误,我们可以看到这个函数的一个有趣的特征:每个连续的局部变量都是通过将一个函数应用于前一个函数来创建的。唯一的例外是第一个,它使用函数的参数。结果是最终的局部变量。
pipe
只是一种使它更具声明性的方法,并消除了对所有局部变量(甚至参数名称)的需要。这等价于:
const getUpperAddr = pipe(
getUserConfig,
JSON.parse,
prop('address'),
prop('addrLine1'),
toUpper
);
这与上面的签名相同,returns相同输入的相同结果。如果你能用第一种格式写你的函数,你可以机械地改成pipe
。过了一会儿,这就变成了第二天性,你可以跳过第一步。