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: []}) }
Advertisement
Answer
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))