我现在正在学习 JS 库 Ramda。似乎有一种我无法正确解决的模式。例如我有这个代码。
const filterPayments = filter => payments =>
r.filter(
r.allPass([
typePred(filter),
amountPred(filter),
accountPred(filter),
currencyPred(filter)
]),
payments
);
现在看来,我距离使其自由化已经不远了。我似乎找不到正确的方法。
此外,我在制作像这样的完全功能性且无点的逻辑函数时遇到了麻烦:
const amountPred = filter => p =>
r.and(p.betrag >= filter.amount.min, p.betrag <= filter.amount.max);
也许有人可以指出我正确的方向或提供一些指导?
最佳答案
我提供的指导是坚持你目前拥有的:)
我可以向您展示一个示例,说明您所拥有的内容的无点翻译可能是什么样子,尽管生成的代码读起来非常糟糕,而且实际上只适合进行心理体操。
首先,付款
出现在函数表达式两侧的最终位置,因此我们可以简单地将其删除。
const filterPayments = filter =>
R.filter(
R.allPass([
typePred(filter),
amountPred(filter),
accountPred(filter),
currencyPred(filter)
]));
接下来我们可以处理传递给R.allPass
的函数列表
R.allPass(R.map(p => p(filter), [typePred, amountPred, accountPred, currencyPred]))
现在我们可以通过翻转 R.map
将其推向末尾来开始删除 filter
参数。
R.allPass(R.flip(R.map)([typePred, amountPred, accountPred, currencyPred])(p => p(filter))
现在让我们创建filter
并将参数传递给p => p(filter)
,而不是关闭它,使其:
R.allPass(R.flip(R.map)
([typePred, amountPred, accountPred, currencyPred])
(R.applyTo(filter)))
现在开始形成像 h(g(f(a)))
这样的形状,我们可以使用 R.pipe
将其转换为无点,R.compose
、R.o
等
const filterPayments = R.compose(
R.filter,
R.allPass,
R.flip(R.map)([typePred, amountPred__, accountPred, currencyPred]),
R.unary(R.applyTo) // R.unary is needed here to tell Ramda only to expect the first argument in this composition
)
这为我们提供了一个现在应该相当于无积分形式的 filterPayments
的函数。
您的 amountPred
示例变得更加复杂,我想您之后会同意您已经拥有的是两者之间更好的选择。
同样,我们首先尝试将参数插入表达式每一侧的末尾:
filter => p =>
both(
x => x >= filter.amount.min,
x => x <= filter.amount.max
)(p.betrag)
然后我们可以删除p
:
filter => R.o(
both(
x => x >= filter.amount.min,
x => x <= filter.amount.max
),
prop('betrag'))
传递给both
的函数也可以交换:
filter => R.o(
both(
R.flip(R.gte)(filter.amount.min),
R.flip(R.lte)(filter.amount.max)
),
prop('betrag'))
现在要解决filter
问题,我们可以使用R.converge
将相同的参数传递给多个函数,然后将每个函数的结果组合在一起。
filter => R.o(
R.converge(both, [
f => R.flip(R.gte)(R.path(['amount', 'min'], f),
f => R.flip(R.lte)(R.path(['amount', 'max'], f)
])(filter),
prop('betrag'))
现在 f
位于结束位置,因此可以通过组合删除它:
filter => R.o(
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])(filter),
prop('betrag'))
将 filter
放到最后会变得非常困惑,涉及翻转组合函数。
filter => R.o(
R.flip(R.o)(R.prop('betrag')),
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])
)(filter)
最后...
const amountPred = R.o(
R.flip(R.o)(R.prop('betrag')),
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])
)
...将其与您的原件进行比较,我知道我更喜欢阅读哪一个:
const amountPred = filter => p =>
p.betrag >= filter.amount.min && p.betrag <= filter.amount.max
关于javascript - 在 Ramda 中做一些无积分的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51104942/