簡體   English   中英

在Ramda中使事情毫無意義

[英]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.pipeR.composeRo等將其轉換為無點形式。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM