简体   繁体   中英

Ramda: rewriting to point free style

I use the following function to send some data to a React component by wrapping it in a higher-order component:

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)
  )

I'm familiar with the concepts of functional programming, but still relatively new to the Ramda library. Now I'd like to rewrite this code using Ramda so that ownProps and getChapter can get eliminated, if only as an academic exercise.

It seems like I should eliminate ownProps first because of the order of the arguments? Although I'm not even sure of that.

Any help would be greatly appreciated!

PS. I'm aware that in the code above ownProps.section would be more readable and preferred to prop('section', ownProps) , ceteri paribus, but I expect that the prop function lies on the path to a point-free equivalent of the code above, hence their inclusion.

Could this be done? Sure. Here's one version:

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

The most unusual function in there is Ramda's useWith , which acts approximately like useWith(f, [g, h])(x, y) ~> f(g(x, y), h(x, y)) . This is not a standard functional language construct, only one that helped make point-free some functions that were difficult to do so. It was mostly useful, though, before ES6/ES2015 became ubiquitous.

You can see this in action on the Ramda REPL .


Should you do this? Well, you said it's an academic exercise, so perhaps. But I find this much less readable than the original. This seems to me useful only as a way to learn some of the features of Ramda. I wouldn't put it into production.

In addition to Scott's answer this is another possible variant:

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

And if you call it with the order of the arguments reversed you don't need the flip on the filter .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM