如何使用R.pipe多个参数?

Fla*_*nix 1 javascript functional-programming ramda.js

背景

我正在学习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!?
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

_arity的第一个参数必须是不大于10的非负整数

我不知道如何解决这个问题.我该怎么做?

你可以在这里看到它.

Sco*_*yet 6

有很多方法可以编写这样的功能.我知道你的目标是学习如何使用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"
Run Code Online (Sandbox Code Playgroud)

现在的问题是:

  1. 为什么你的功能不起作用?
  2. 你怎么能让它发挥作用?
  3. 你如何按需pipe工作?

为什么你的功能不起作用?

这很简单:pipe将许多函数作为参数,至少需要一个.您提供的第一个参数是getSQLQuery( queryParams ),使用参数调用的结果getSQLQuery.这是一个字符串,而不是一个函数.因此,当您尝试将其包装时pipe,它会失败.(关于'arity'的注释与Ramda的内部有关:它使用第一个函数pipe来确定结果函数应该采用多少参数.)

你怎么能让它发挥作用?

我在上面给出了答案.MarioF的答案是对初始功能的最小改动.

但这些都不是那么简单

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"
Run Code Online (Sandbox Code Playgroud)

你如何按需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;
}
Run Code Online (Sandbox Code Playgroud)

遗忘的细节,特别是如何getUserConfig工作的,而忘记任何潜在的错误,我们可以看到这个函数的一个有趣的功能:每次连续局部变量是通过将一个函数之前,一个创造.唯一的例外是第一个,它使用函数的参数.结果是最终的局部变量.

pipe 只是一种使这更具说明性的方法,并且不需要所有局部变量(甚至参数名称.)这是等效的:

const getUpperAddr = pipe(
    getUserConfig,
    JSON.parse,
    prop('address'),
    prop('addrLine1'),
    toUpper
);
Run Code Online (Sandbox Code Playgroud)

它具有与上面相同的签名,并为同一输入返回相同的结果.如果您可以用第一种格式编写函数,则可以机械地更改为pipe.过了一会儿,这成了第二天,你可以跳过第一步.