Javascript — Использование compose с уменьшением

#javascript #functional-programming

#javascript #функциональное программирование

Вопрос:

Я изучаю функциональное программирование с помощью javascript. Я узнал, что для уменьшения необходимы 2 параметра. Накопитель и фактическое значение, и если мы не указываем начальное значение, используется первый аргумент. но я не могу понять, как purchaseItem функции работают в приведенном ниже коде. кто-нибудь может, пожалуйста, объяснить.

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

Комментарии:

1. Вы уверены, что это правильная compose функция (вы добавили {} при добавлении console.log() во внутреннюю функцию)?

2. Действительно, составная функция, которая не возвращает выходные данные композиции, здесь будет не очень полезна. Хорошее место @NickParsons

3. @NickParsons Спасибо, что указали.. Я обновил код правильной функцией

Ответ №1:

Может быть, это поможет, если вы возьмете минимальный рабочий пример и визуализируете структуру вывода:

 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)))))  

Пожалуйста, обратите внимание, что нам нужно id разрешить повторное использование пустого массива.

Комментарии:

1. К делу. сделало работу функции очень простой

Ответ №2:

Это способ создания конвейера функций, при котором выходные данные одной функции используются в качестве параметра следующей, так что в итоге мы получаем составную функцию, которая эффективно

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

Написание reduce от руки может помочь в понимании:

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