Я бы посоветовал придерживаться того, что у вас есть на данный момент :)
Я могу показать вам пример того, как могут выглядеть безточечные переводы того, что у вас там есть, хотя полученный код довольно ужасен для чтения и на самом деле годится только для сеанса умственной гимнастики.
Во-первых, payments
появляется в конечной позиции обеих сторон функционального выражения, так что мы можем просто отбросить его.
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]))
Теперь мы можем начать удалять аргумент filter
, перевернув R.map
, чтобы подтолкнуть его к концу.
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
person
Scott Christopher
schedule
30.06.2018