ramda.js - 函数式编程 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 函数都像reduce
这里一样。它们以这样的方式进行柯里化,例如,fn(a)(b)(c)
、fn(a, b)(c)
和fn(a)(b, c)
都fn(a, b, c)
返回相同的值。一小组 Ramda 函数是不同的。
通常这是因为 Ramda 对可变参数函数的处理(即那些接受不同数量参数的函数)。Ramda 不喜欢暴露可变参数函数。(由于历史原因,pipe
andcompose
和他们的亲属仍然是可变参数,但其他的并不多。)但是 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 write
anyPass([gt, sameParity], 10, 8) ? If so, the input to
anyPass` 变成“一个函数数组,后面跟着任意数量的其他参数”——几乎不是一个规范的函数。
或者,我们可以重组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)
这些天,逐一传递论点实际上已成为我的首选风格。
推荐阅读
- azure - Azure API 管理速率限制(按 Json 正文)
- python - 有没有办法让不和谐的机器人屏幕共享网站
- android - 显示键盘时全屏 AlertDialog 有 janky 动画
- reactjs - jsonserver 不使用重写器重定向
- angular - Kubernetes 中的 Angular 和 dotnetcore 连接抛出 404
- angular - 使用 fakeasync 时出错 - 但它在其他地方有效
- python - kivy Python:等待登录密码检查代码时的动画图片
- python - 多索引数据框删除每组最大值的行
- android - 关于 CRUD 操作的问题
- flutter - 如何在我的颤振应用程序中将 BluetoothDevice 对象存储到共享首选项(不支持 BluetoothDevice 对象类型)