【问题标题】:Idiomatic Ramda for generating higher order functions?用于生成高阶函数的惯用 Ramda?
【发布时间】:2016-05-28 14:38:51
【问题描述】:

我的目标是创建一个自定义映射函数,该函数首先需要过滤列表以保留,例如,在对每个项目调用提供的函数之前,仅保留偶数项。我确实需要对函数进行柯里化,并且第一个参数是函数,而不是列表。我相信签名应该是这样的:(a -> b) -> [a] -> [b]

当然有很多方法可以做到这一点。这是我第一次尝试的样子。

var isEven = x => x % 2 === 0;

var filterEvensMap = R.curry((fn, items) => R.map(fn, R.filter(isEven, items)));

filterEvensMap(R.negate, [1,2,3,4]); // [-2, -4]

但是,由于上面使用了带有 fnitems “胶水参数”的匿名函数,我不确定这是否是 Ramda 的预期使用方式。

下面我介绍了另一种方法。它似乎更符合 Ramda 的精神,但我不确定我是否过于复杂了。

var filterEvensMap = R.compose(
  R.flip,
  R.uncurryN(2)
)(R.compose(
  R.flip(R.map),
  R.filter(isEven)
));

我是否过于复杂了多个 compose 和 uncurryN?有没有更惯用的方法来实现这一点?根据您的经验,这重要吗?

提前致谢。

【问题讨论】:

    标签: javascript functional-programming higher-order-functions currying ramda.js


    【解决方案1】:

    如果您发现 Haskell 签名有用,您可能会发现 point-free generator (source) 也很有用。如果要简化表达式,可以输入与 JS 代码等效的 Haskell:

    filterEvensMap = \fn items -> map fn (filter isEven items)
    

    它会给你一个无积分的等价物:

    filterEvensMap = (. filter isEven) . map
    

    然后使用 Ramda 翻译回 JS:

    var filterEvensMap = R.curry(R.compose(R.compose(R.filter(isEven)), R.map))
    

    根据您的经验,这重要吗?

    我会选择最易读的表达式,在这种情况下可能是原始表达式。无点很有趣,可以在某些地方增加清晰度,但它也会大大降低可读性,或者至少降低理解水平。

    【讨论】:

    • 嘿,感谢您的提示,pointfree.js 看起来真的很有帮助。但是,在 OP 中的预期行为和从无点 Haskell 表达式派生的 Ramda 表达式之间存在轻微的不匹配:过滤需要在原始 vals 上进行,而不是在映射的 vals 上进行。这是一个显示差异的链接:goo.gl/KVX4Kv。我对 Haskell 语法不太熟悉,所以我仍在尝试找出问题所在。
    • 哦,我弄错了,应该是compose(pipe(filter(f)), map),但由于某种原因它在 Ramda 中不起作用。我的猜测是自动柯里化和可变参数 compose/pipe 把事情搞砸了,但你可以在这里看到它在 vanilla JS 中工作:jsfiddle.net/xs56h0vb
    • 再次感谢!我将其标记为已回答,因为我拥有继续编程所需的一切。我现在知道我在问题中所指的是一个名为“pointfree”的概念,并且并不总是有必要仅仅因为它是可能的而编写一个 pointfree 表达式。但是当我想玩的时候,有pointfree.js
    • 刚刚提交了一个编辑,以将您的示例 Ramda 代码包装在 R.curry 中(使用 R.compose 创建的函数默认情况下不咖喱)。原始版本也有一个轻微的重构,var fmap = R.uncurryN(2, f => R.compose(R.map(f), R.filter(isEven))) 也可以删除额外的 items 参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多