【问题标题】:How can I compose functions when the input is needed to build the pipeline?当需要输入来构建管道时,如何组合函数?
【发布时间】:2016-06-19 01:14:38
【问题描述】:

我正在尝试使用 Ramda 库在 javascript 中学习一些函数式编程,但我不断遇到我编写一堆函数然后必须将输入传递给结果两次的情况。下面的工作代码就是一个例子:

const search = R.invoker(1, 'search');
const substring = R.invoker(2, 'substring');
const lSplit = (pat, s) => R.compose(substring(0), search(pat))(s)(s);
lSplit(/ /, 'foo bar');

lSplit 接受一个正则表达式和一个字符串,定位字符串中的第一个匹配项,并返回匹配项左侧的所有内容。最后一行计算为'foo'。有必要将s 传递给组合函数两次:第一次找到模式并构建子字符串函数,然后第二次在字符串上运行组合函数。该代码有效,但(s)(s) 似乎不优雅。

我编写了一个名为 twice 的函数,它稍微整理了一下,但并没有真正解决不优雅的问题:

const search = R.invoker(1, 'search');
const substring = R.invoker(2, 'substring');
const twice = f => d => f(d)(d);
const lSplit = pat => twice(R.compose(substring(0), search(pat)));

lSplit(/ /)('foo bar');

是否有一种更简洁或更优雅的方式来处理需要在将数据输入管道之前使用数据来构建管道的情况?

【问题讨论】:

    标签: javascript functional-programming ramda.js


    【解决方案1】:

    您的组合看起来很乱的原因是因为您正在组合一个二元函数search 和一个三元函数substring。更糟糕的是,“管道”参数发生在三元函数的中间

                   _ search(/ /, s)
                  /
    substring(0, /, s)
    

    不用担心没有点,我只会写最能表达它的函数

    const lSplit = (pat, s) => substring(0, search(pat,s), s);
    

    它并不聪明,但它是可读的。我的建议是完成。

    【讨论】:

    • 谢谢!我想我仍在试图弄清楚编写功能代码的“正确”方式是什么(并不是真的有这样的事情)。我对免费点有点犹豫。你的方式更具可读性。
    • 同意。 Ramda 有一些巧妙的功能,例如 useWithconverge,而 Sanctuary 还公开了其他功能,例如 meldS-combinator。这些有时非常有用且可读性很强,但它们往往降低可读性,应该跳过。
    猜你喜欢
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 2020-06-12
    相关资源
    最近更新 更多