【问题标题】:Make function pointfree using Ramda使用 Ramda 使函数无点
【发布时间】:2017-10-07 17:42:49
【问题描述】:

如何使以下函数无点(使用 Ramda)?

const prefixAll = R.curry((prefix, list) => R.map(R.concat(prefix), list))

【问题讨论】:

  • xprod 可能也值得一看。它虽然输出数组... R.xprod(["a"], ["b", "c", "d"]) 返回 [["a", "b"], ["a", "c"], ["a", "d"]]

标签: javascript functional-programming ramda.js pointfree


【解决方案1】:

我将代码输入pointfree.io(好吧,我首先将其转换为Haskell \prefix list -> map (prefix ++) list),然后返回:

map . (++)

所以等效的 JavaScript 应该是:

const prefixAll = R.compose(R.map, R.concat);

当我在ramda's REPL 中测试这个时,我想我得到了想要的结果。

【讨论】:

  • Ramda 函数默认是柯里化的,所以我认为这里不需要 R.curry
  • @marzelin:谢谢。我实际上对 ramda 一点也不熟悉,但是在几种语言中来回转换通常可以解决问题。
  • 好吧,当两个参数同时给出时它不起作用
  • @marzelin:根据我的阅读,我认为这是由于 compose 本身进行了一些柯里化,但由于某种原因未能发现有两个参数。
  • 所有提供给compose 的参数都传递给第一个函数,但在这种情况下,需要将第二个参数传递给组合的结果。 useWith 似乎是完成这项工作的合适工具。
【解决方案2】:

另外,这应该可以工作

R.useWith(R.map, [R.concat, R.identity])

R.identity 是为了获得适当的功能,请参阅@scott-sauyet 的评论。)

see Ramda REPL

P.S:但我个人认为,compose 更好——使用参数的部分应用是更实用的方法。例如R.compose(R.map, R.concat)('a')(['a','b'])

【讨论】:

  • 如果你确实使用它,我会推荐一个轻微的变体:prefixAll = R.useWith(R.map, [R.concat, R.identity])。这具有与上述相同的行为,但此函数将正确报告其数量。
  • @ScottSauyet 你能详细说明一下吗?我不明白这一点。谢谢。
  • 添加identity只是说有第二个参数,但在传入map之前没有修改。 R.useWith(R.map, [R.concat]).length; //=> 1,但R.useWith(R.map, [R.concat, R.identity]).length; //=> 2。我发现让我的函数正确报告它们的参数(它们接受的参数的数量)是一个好公民的问题。当然,Ramda 的柯里化会使水变得浑浊,因为它允许你使用这些函数和不同的参数,但我认为完整数量的参数是正确的行为。
  • @ScottSauyet 我明白了。非常感谢,有道理。
【解决方案3】:

IMO 最简单的方法是使用在这种情况下通过 R.lift 提升 R.concat 函数实现的理解。

const prefixAll = R.lift(R.concat);
prefixAll(['hi-'], ['you', 'there']); // => ["hi-you", "hi-there"]

请注意,前缀必须作为单元素数组传递。 这个函数是 Ramda 自动为你柯里化的。

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    • 2019-09-21
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多