1

I am learning functional programming with javascript. I have learned that 2 parameters are needed for reduce. Accumalator and the actual value and if we don't supply the initial value, the first argument is used. but I can't understand how the purchaseItem functions is working in the code below. can anyone please explain.

const user = {
    name: 'Lachi',
    active: true,
    cart: [],
    purchases: []
}
let history = []
const compose = (f, g) => (...args) => f(g(...args))

console.log(purchaseItem(
    emptyCart, 
    buyItem, 
    applyTaxToItems, 
    addItemToCart
)(user, {name: 'laptop', price: 200}))

function purchaseItem(...fns) {
    console.log(fns)
    return fns.reduce(compose)
}

function addItemToCart (user, item) {
    history.push(user)
    const updatedCart = user.cart.concat(item)
    return Object.assign({}, user, { cart: updatedCart })
}

function applyTaxToItems(user) {
    history.push(user)
    const {cart} = user
    const taxRate = 1.3
    const updatedCart = cart.map(item => {
        return {
            name: item.name,
            price: item.price * taxRate
        }
    })
    return Object.assign({}, user, { cart: updatedCart })
}

function buyItem(user) {
    history.push(user)
    return Object.assign({}, user, { purchases: user.cart })
}

function emptyCart(user) {
    history.push(user)
    return Object.assign({}, user, {cart: []})
}
3
  • 2
    Are you sure that's the correct compose function (did you add the {} when adding console.log() to the inner function)? Commented Aug 24, 2020 at 11:40
  • 1
    Indeed, a composed function that doesn't return the output of the composition isn't going to be very useful here. Good spot @NickParsons Commented Aug 24, 2020 at 11:44
  • @NickParsons Thanks for pointing.. I have updated the code with the correct function Commented Aug 24, 2020 at 11:47

2 Answers 2

4

Maybe it helps if you take a minimal working example and visualize the output structure:

const comp = (f, g) => x => f(g(x));

const inc = x => `inc(${x})`;
const sqr = x => `sqr(${x})`;
const id = x => `id(${x})`;

const main = [sqr, inc, inc, inc].reduce(comp, id);

console.log(main(0)); // id(sqr(inc(inc(inc(0)))))

Please note that we need id to allow redicung an empty array.

Sign up to request clarification or add additional context in comments.

1 Comment

To the point. made the working of the function very claer
0

It's a way of creating a pipeline of functions whereby the output from one function is used as the parameter of the next, so we end up with a composed function that is effectively

(...args) => 
    emptyCart( 
        buyItem( 
            applyTaxToItems( 
                addItemToCart(...args) 
            ) 
        ) 
    )

Writing the reduce out in longhand might help in understanding:

fns.reduce((acc, currentFn) => compose(acc, currentFn))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.