首页 > 解决方案 > 函数式编程 RamdaJs arity 问题

问题描述

我对 Ramda 和整个 FP 中的功能的准确性有疑问。

在 RamdaJs 中,一些函数接受 2,3 个参数,但其中一些是柯里化的(接受一个或两个参数并返回另一个函数)。

例如:

const isBlackCard = R.anyPass([isClub, isSpade]);
isBlackCard({rank: '10', suit: '♣'}); //=> true

anyPass - 返回另一个等待对象的函数。

R.reduce(R.add, 0, [1, 2, 3, 4])

在这种情况下,reduce 等待所有参数并返回结果 => 10

如果我遵循前面的示例,为什么 reduce 与 anyPass 不同,如下所示:

const adder = R.reduce(R.add, 0);
const sum = adder([1, 2, 3, 4]); //10

这样它们看起来就一样了。

那么为什么它们不相似,以及何时创建一个或另一个是否有任何规则。

如果我们从一开始就为给定功能选择了错误的方式,那么将来将很难更改,因为它将在很多地方使用。

此外,一些库使用与 curried 和 uncurried 类似的名称,但我不喜欢这个想法,因为它类似于复制。

谢谢

标签: ramda.js

解决方案


大多数 Ramda 函数都像reduce这里一样。它们以这样的方式进行柯里化,例如,fn(a)(b)(c)fn(a, b)(c)fn(a)(b, c)fn(a, b, c)返回相同的值。一小组 Ramda 函数是不同的。

通常这是因为 Ramda 对可变参数函数的处理(即那些接受不同数量参数的函数)。Ramda 不喜欢暴露可变参数函数。(由于历史原因,pipeandcompose和他们的亲属仍然是可变参数,但其他的并不多。)但是 Ramda 经常使用用户提供的可变参数函数。提供给anyPassallPass不必是一元的函数。在这里,我们将二进制函数传递给anyPass

const sameParity = (a, b) => a % 2 == b % 2

const foobar = R.anyPass ([gt, sameParity])

foobar (10, 8)  //=> true
foobar (10, 14) //=> true
foobar (5, 7)   //=> true
foobar (5, 14)  //=> false
foobar (5, 8)   //=> false

我们可以传递三元甚至更高元的函数。

但是,我们如何期望将参数直接传递给这些函数呢?我们可能会写anyPass([isSpade, isClub], {rank: 'K', suit: '♣'}). But would we also writeanyPass([gt, sameParity], 10, 8) ? If so, the input toanyPass` 变成“一个函数数组,后面跟着任意数量的其他参数”——几乎不是一个规范的函数。

或者,我们可以重组anyPass,使其接受一个函数数组,然后是一个参数数组。这听起来不错,直到您意识到这可能是多么不符合人体工程学:isBlackCard(myCard)您必须调用. 而不是isBlackCard([myCard]). 这感觉真的不对。

因此,对于这几个函数,有一个折衷方案:它们只返回一个函数,从不尝试将其应用于您的值。


你问这个:

如果我遵循前面的示例,为什么 reduce 与 anyPass 不同,如下所示:

const adder = R.reduce(R.add, 0);
const sum = adder([1, 2, 3, 4]); //10

嗯,事实上就是这样。像大多数 Ramda 函数一样,您可以reduce使用其参数的任何初始子集调用 ,并取回等待其他函数的函数。

const adder = R.reduce(R.add, 0);
const sum = adder([1, 2, 3, 4]);

console.log(sum)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

唯一真正的区别是您也可以将其称为reduce(add, 0, [1, 2, 3, 4]).

但是如果你想要一致性,除了 Ramda 中的几个实际可变参数函数之外,你可以以这种风格调用所有这些函数,而不会损失功能:

reduce (add) (0) ([1, 2, 3, 4])
anyPass ([isClub, isSpade]) (myCard)

这些天,逐一传递论点实际上已成为我的首选风格。


推荐阅读