这里的大多数 Ramda 函数都类似于 reduce。它们以这样的方式进行咖喱,例如,fn(a)(b)(c)、fn(a, b)(c)、fn(a)(b, c) 和 fn(a, b, c) 都返回相同的值。一小部分 Ramda 函数是不同的。
这通常是因为 Ramda 对可变参数函数的处理(即那些接受不同数量参数的函数)。 Ramda 不喜欢暴露可变参数函数。 (由于历史原因,pipe 和compose 及其亲属仍然是可变参数,但其他的并不多。)但是 Ramda 经常使用用户提供的可变参数函数。提供给anyPass 或allPass 的函数不必是一元的。这里我们将二进制函数传递给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)
如今,逐一传递参数实际上已成为我的首选风格。