Search code examples
javascriptramda.jspointfree

How to write point-free functional JS using Ramda


I have an array of objects

const myNumbers = [
  {
   top: 10,
   bottom: 5,
   rate: 5
  },
  {
   top: 9,
   bottom: 4,
   rate: 3
  },
];

I want to run a few functions that make the numbers usable before I do anything with them;

const addTen = r.add(10);
const double = r.multiply(2);

And a function that accepts the numbers and does some maths:

const process = (top, bottom, rate) => r.multiply(r.subtract(bottom, top), rate)

So my final function looks like

muNymbers.map(({ top, bottom, rate }) =>
  process(addTen(top), double(bottom), rate)
);

Just looking at this code you can see both functions are already becoming very nested and not particularly clear. My real problem is slightly more complicated again, and I am struggling to see how I can make this point-free when picking different values for different operations.


Solution

  • Here is a point-free approach. The main functions you're looking for are pipe, evolve and converge. I'm not sure if this is the best way, it's just the best I could think of:

    const { add, converge, evolve, map, multiply, pipe, prop, subtract } = R;
    
    const myNumbers = [
        { top: 10, bottom: 5, rate: 5 },
        { top: 9, bottom: 4, rate: 3 },
    ];
    
    const process = pipe(
    
        evolve({
            top: add(10),
            bottom: multiply(2),
        }),
    
        converge(multiply, [
    
            converge(subtract, [
                prop('bottom'),
                prop('top'),
            ]),
    
            prop('rate'),
        ]),
    );
    
    console.log(map(process, myNumbers));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>