Skip to content

Instantly share code, notes, and snippets.

@gustavorodarte
Created September 8, 2021 18:02
Show Gist options
  • Save gustavorodarte/2152ee0bbfbd7b66ce5a5ca1b6693036 to your computer and use it in GitHub Desktop.
Save gustavorodarte/2152ee0bbfbd7b66ce5a5ca1b6693036 to your computer and use it in GitHub Desktop.
Progamação Funcional com Crocks
const { map, filter } = require('crocks/pointfree');
const reject = require('crocks/pointfree/reject');
const Pair = require('crocks/Pair');
const log = require('../lib/log');
const List = require('crocks/List');
const identity = require('crocks/combinators/identity');
const cart = [
{ "name": "Biscuits", "type": "regular", "category": "food", "price": 2.0 },
{ "name": "Monitor", "type": "prime", "category": "tech", "price": 119.99 },
{ "name": "Mouse", "type": "prime", "category": "tech", "price": 25.50 },
{ "name": "dress", "type": "regular", "category": "clothes", "price": 49.90 },
];
const activeCoupons = [{ discount: 20, type: "prime" }, { discount: 10, type: "regular" }];
// displayItem : Item -> String
const displayItem = ({ name, type, category, price }) => `${name} || ${type} || ${category} || ${price}`;
// displayItems : [ Item ] -> [ String ]
const displayItems = map(displayItem);
// Item -> Boolean;
const isPrime = ({ type }) => type === "prime"
// [ Item ] -> [ Item ]
const primeItems = filter(isPrime);
// [ Item ] -> [ Item ]
const notPrimeItems = reject(isPrime);
const getDiscountedPrice = (discount) => (item) => ({ ...item, price: (item.price * (1 - discount / 100)) });
// [ Coupons] -> [ Item ] -> [ Item ]
const applyCoupon = (coupons) => (items) => {
const discounts = List(coupons.map(({ discount }) => discount));
return discounts.map(getDiscountedPrice).ap(List(items)).toArray();
}
// [ Item ] => Pair [ Item ] [ Item ]
const splitPrime = (items) => Pair(primeItems(items), notPrimeItems(items));
const splitCoupons = (coupons) => Pair(primeItems(coupons), notPrimeItems(coupons));
// Pair [ Items ] -> Pair [ Coupons ] -> [Items];
const calcOrderDiscounts = (splittedItems) => (splittedCoupons) => {
const regularItemsWithDiscounts = splittedCoupons.map(applyCoupon).ap(splittedItems).snd();
const primeItemsWithDiscounts = splittedCoupons.swap(identity, identity)
.map(applyCoupon).ap(splittedItems).snd();
return {
regularItemsWithDiscounts,
primeItemsWithDiscounts,
}
}
// [ Item] => [Item] -> Number;
const totalCost = (regularItemsWithDiscounts) => (primeItemsWithDiscounts) => {
const totalRegular = regularItemsWithDiscounts.reduce((acc, i) => acc + i.price, 0);
const totalPrime = primeItemsWithDiscounts.reduce((acc, i) => acc + i.price, 0)
return totalRegular + totalPrime;
}
// [ Item ] -> [ Coupons ] -> Number
const makeOrder = (items) => (coupons) => {
const splittedItems = splitPrime(items);
const splittedCoupons = splitCoupons(coupons);
const { regularItemsWithDiscounts, primeItemsWithDiscounts } = calcOrderDiscounts(splittedItems)(splittedCoupons);
return totalCost(regularItemsWithDiscounts)(primeItemsWithDiscounts)
}
log(makeOrder(cart)(activeCoupons))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment