Created
September 8, 2021 18:02
-
-
Save gustavorodarte/2152ee0bbfbd7b66ce5a5ca1b6693036 to your computer and use it in GitHub Desktop.
Progamação Funcional com Crocks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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