[英]Making something point-free in Ramda
我現在正在學習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);
也許有人可以為我指明正確的方向或提供一些指導?
我提供的指導是堅持使用您目前擁有的東西:)
我可以向您展示一個示例,說明您所擁有內容的無點翻譯可能會是什么樣子,盡管所得到的代碼非常可怕,而且僅對心理體操有益。
首先, 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]))
現在,我們可以通過翻轉R.map
將其推到末尾來開始刪除filter
參數。
R.allPass(R.flip(R.map)([typePred, amountPred, accountPred, currencyPred])(p => p(filter))
現在讓make 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
, Ro
等將其轉換為無點形式。
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
我已經開始做與Scott Christopher一樣的工作,並且將主要功能重構為無點,從一開始就知道我的建議幾乎可以肯定不要為此而煩惱。 我找到了我的無點版本,它比我預期的要簡單。 在開始謂詞之前,我希望先看看Scott的解決方案。
他做了我會做的很多事情,而且可能比我做的更好。 當然,他以類似的建議告終。 我總是試圖建議人們不要出於無聊而迷戀。 當它使您的代碼更簡潔易懂時,請使用它。 不使用時請勿使用。
除了我最終給出了一個稍微好一點的main函數的無點版本之外,我什么都不會回答,並且想考慮一下:
const filterPayments = pipe(
juxt([typePred, amountPred, accountPred, currencyPred]),
allPass,
filter
)
盡管這很干凈,但我認為它的可讀性不如您的原始版本,因此我不建議您這樣做。 但是,如果您真的想要無積分,這是有可能的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.