javascript - 你将如何重写这个多参数函数,最终实现无点风格?
问题描述
我是 Ramda 和函数式编程的新手,我想知道有人会如何改进下面的代码或将其转换为无点样式
const doc = {
passwordRecovery: {
requested: true,
expiresAt: new Date(Date.now() + 1000).toISOString(),
code: 'abc'
}
}
const req = {
password: '123',
passwordRecovery: {
code: 'abc'
}
}
const pathCode = R.path(['passwordRecovery', 'code'])
const isValidCode = R.curry(
(doc, req) => R.all(
R.hasPath(['passwordRecovery', 'code'], req),
R.pathEq(['passwordRecovery', 'requested'], true, doc),
R.compose(R.complement(R.isNil), pathCode)(doc),
R.equals(pathCode(req), pathCode(doc)),
R.pipe(
R.path(['passwordRecovery', 'expiresAt']),
Date.parse,
R.gte(R.__, Date.now()),
)(doc)
)
);
isValidCode(doc)(req)
解决方案
几个建议:
避免混淆
不熟悉柯里化的人经常会说同样的话:add(1)(2)
当你可以做的时候为什么要做add(1, 2)
?他们是对的。这个例子根本不适合咖喱。
如果您的团队刚刚熟悉函数式编程,请不要让他们感到不必要的困惑。如果您可以一次性提供所有参数,请执行以下操作:
isValidCode(doc, req); // not isValidCode(doc)(req);
不要为了使用 Ramda 而使用 Ramda
这:R.equals(pathCode(req), pathCode(doc))
与: 相同pathCode(req) === pathCode(doc)
。
如果您确实想使用 Ramda,请考虑eqBy
:
eqBy(pathCode, req, code);
Pointfree 不是唯一的方法
这当然是一种有趣的编写函数的方式,但它不能成为目标。假设您需要检查a
等于'foo'
和b
等于'bar'
:
这是无点函数:
const fn = useWith(and, [equals('foo'), equals('bar')]);
比这更好:
const fn = (a, b) => a === 'foo' && b === 'bar';
?
是否all
正确调用?
根据文档,all
需要一个函数和一个列表:
all(x => x === 42)([41, 42, 43]);
除非我弄错了,否则您所做的是all
使用每个函数调用的结果进行调用。例如
all(true, false, true, ...);
避免__
占位符
gte(__, Date.now())
可以改为flip(gte)(Date.now())
始终如一
在一种情况下,您允许将路径设置为undefined
:
// true even for `{passwordRecovery: {code: undefined}}`
hasPath(['passwordRecovery', 'code'], req);
而在另一个你没有:
compose(R.complement(R.isNil), pathCode)(doc)
保持一致将允许这样做:
const notNil = complement(isNil);
both(pathSatisfies(notNil, pathCode), req, doc)
推荐阅读
- python - 从两个目录中的文件导入函数
- asp.net-core - 如何在 ASP.Net 核心中使用 Outlook 邮件 API?
- flutter - Flutter 电话身份验证 FirebaseAuthInvalidCredentialsException
- powershell - Powershell 将 f5 键发送到边缘
- java - 根据调用的方法在 Spring REST API 中应用身份验证过滤器
- scala - 多类分类,使用 Spark 在 Scala 中更好地显示原始预测
- python - 如何塑造一维卷积神经网络
- sql - 使用存储过程回滚
- android - Android - 带有 IdentityServer 的 Google oauth
- spring-boot - Spring Kafka - 消费者:未收到消息