Ramda:重写为点自由风格

Ramda: rewriting to point free style

我使用以下函数通过将一些数据包装在高阶组件中将其发送到 React 组件:

import { equals, filter, isNil, prop, where } from 'ramda'

const example = getChapter => ownProps =>
  filter(
    where({
      sectionId: equals(prop('section', ownProps)),
      subsectionId: isNil,
      sub2sectionId: isNil,
      sub3sectionId: isNil
    }),
    prop('getContents', getChapter)
  )

我熟悉函数式编程的概念,但对 Ramda 库还是比较陌生。现在我想用 Ramda 重写这段代码,这样 ownPropsgetChapter 就可以被淘汰,如果只是作为一个学术练习的话。

看来我应该先去掉ownProps,因为参数的顺序?虽然我什至不确定。

如有任何帮助,我们将不胜感激!

PS。我知道在上面的代码中 ownProps.sectionprop('section', ownProps) 更可读并且更受欢迎,其他条件不变,但我希望 prop 函数位于无点的路径上等同于上面的代码,因此包含它们。

可以这样做吗?当然。这是一个版本:

const example2 = useWith(flip(filter), [prop('getContents'), pipe(
  prop('section'),
  equals,
  objOf('sectionId'),
  where,
  both(where({
    subsectionId: isNil,
    sub2sectionId: isNil,
    sub3sectionId: isNil
  }))
)])

其中最不寻常的函数是 Ramda 的 useWith,它的行为与 useWith(f, [g, h])(x, y) ~> f(g(x, y), h(x, y)) 大致相同。这不是一种标准的函数式语言结构,只是一种有助于使一些难以实现的函数变得无意义的结构。不过,在 ES6/ES2015 变得无处不在之前,它最有用。

您可以在 Ramda REPL.

上看到实际效果

你应该这样做吗?好吧,你说这是一个学术练习,也许是这样。但我发现这比原来的可读性差得多。在我看来,这仅作为学习 Ramda 某些功能的一种方式有用。我不会把它投入生产。

除了 Scott 的回答之外,这是另一种可能的变体:

useWith(
  flip(filter),
  [
    prop('getContents'),
    pipe(
      prop('section'),
      equals,
      assoc('sectionId', R.__, {
        subsectionId: isNil,
        sub2sectionId: isNil,
        sub3sectionId: isNil
      }),
      where
    )
  ])

如果您以相反的参数顺序调用它,则不需要 filter 上的 flip