Search code examples
javascriptfunctional-programmingramda.jspointfree

Using Ramda map helper in pointfree way


How can I change this code:

 map(user => assoc('isAdult', isAdult(user), user)

to function pointfree (using Ramda). I was thinking how to do it with useWith, but can't find working implementation.

Any ideas?

import { pipe, prop, gte, __, map, assoc, sortWith, descend } from 'ramda'

const isAdult = pipe(
  prop('age'),
  gte(__, 18)
)

const func = pipe(
  map(user => assoc('isAdult', isAdult(user), user)),
  sortWith([
    descend(prop('isAdult')),
    descend(prop('age')),
  ])
)

export default func

EDIT (more info):

I want to create a function that returns array of objects extended by the isAdult key. If the user is more than 18 years old, we set the flag to true.

In addition, the function should return users sorted by the flag isAdult and then sorted by the key age.

Sample data:

const data1 = [
  {
    name: 'Cassidy David',
    email: 'sit@Nullaeuneque.co.uk',
    id: 'FC92BF1E-A6FD-E5C1-88AB-183BD1BC59C5',
    position: 1,
    age: 53,
    created_at: '2017-04-07'
  },
  {
    name: 'Gwendolyn Edwards',
    email: 'ut.mi.Duis@elementumsemvitae.net',
    id: '00000001-ED9D-3A88-0D3C-07A148FD43ED',
    position: 2,
    age: 10,
    created_at: '2016-05-21'
  },

Solution

  • I think it's debatable whether trying to make this point-free is useful.

    This is quite readable as is:

    map(user => assoc('isAdult', isAdult(user), user)),
    

    Point-free is a great technique that can sometimes enhance readability. But if it doesn't, I wouldn't bother with it.

    That said, if you do want to try point-free, chain is probably most helpful. Note how chain works for functions: chain(f, g)(x) //=> f(g(x), x).

    So you can write your relevant part as

    map(chain(assoc('isAdult'), isAdult))
    

    You can see this in action on the Ramda REPL.