Ben
Ben

Reputation: 3060

Apply same argument to list of functions, and do an operation between each result

I have a list of functions, each that take the same parameter, and return a number. I want to apply an argument to each function, and perform an operation (in this case subtract) on each successive result:

    const run = item => buyPrice(item) -
                        sellPrice(item) -
                        receivingCost(item);

Is there a clean, pointfree way to create this function?

Upvotes: 1

Views: 501

Answers (3)

mhodges
mhodges

Reputation: 11116

I'm not entirely clear on exactly what you're asking, but is this what you were looking for? The idea is to keep your functions in an array, and then use R.reduce() to subtract the result of each function call for a given item.

EDIT - Updated code to adhere more strictly to Pointfree standards by using function composition.

const reduce = R.reduce;
const curry = R.curry;
const juxt = R.juxt;
const isNil = R.isNil;
var item = {
    buyPrice: 5,
    sellPrice: 8,
    receivingCost: 1
};

const getBuyPrice = R.prop("buyPrice");
const getSellPrice = R.prop("sellPrice");
const getReceivingCost = R.prop("receivingCost");

const fns = [getBuyPrice, getSellPrice, getReceivingCost];
const getItemPrices = juxt(fns);
const subtract = curry((a, b) => isNil(a) ? b : a - b);
const subtractArr = reduce(subtract);
const subtractArrFromFirstValue = subtractArr(null);
const run = R.compose(subtractArrFromFirstValue, getItemPrices);

console.log(run(item));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

Upvotes: 0

Scott Sauyet
Scott Sauyet

Reputation: 50787

This is not entirely point-free, but I think it takes care of certain complexities:

const run = lift((b, s, r) => b - s - r)(buyPrice, sellPrice, receivingCost)

While I'm sure we could create a point-free version of (b, s, r) => b - s - r, I really doubt that we could find one as expressive.

You can see this in action on the Ramda REPL.

Upvotes: 1

Barmar
Barmar

Reputation: 780723

Use Array.prototype.map() to call all the functions in the list, and then Array.prototype.reduce() to do all the subtractions:

function run (item) {
    const funcs = [buyPrice, sellPrice, receivingCost];
    return funcs.map(f => f(item)).reduce((x, y) => x - y);
}

Upvotes: 0

Related Questions