Skip to content

Instantly share code, notes, and snippets.

@MikeBild
Last active April 10, 2017 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikeBild/f71b856b66602ceb7bdea8691569ae09 to your computer and use it in GitHub Desktop.
Save MikeBild/f71b856b66602ceb7bdea8691569ae09 to your computer and use it in GitHub Desktop.
Proof of Concept (recompose) - Bank-Account-System composition with higher-order functions (NodeJS6)
const account = openBankAccount({name: 'Max Muster'})({})
account.deposit(1000)
account.withdraw(800)
account.withdraw(800)
// use compose(...) building block
const { calculateBalance, name, transactions, save} = compose(withBalanceCalculation({}), withStore())(account)
console.log(`${name}: ${calculateBalance()} [${transactions.map(x => x.deposit || 0 - x.withdraw)}]`)
console.log(save())
// same stuff, but use the handy way
// const bankAccountWithBalanceCalculation = withBalanceCalculation({})(account)
// const bankAccountWithStore = withStore()(account)
// console.log(bankAccountWithBalanceCalculation.calculateBalance())
// console.log(bankAccountWithStore.save())
const transferredAccount = openBankAccount({name: 'John Doe'})(account.load(account.save()))
transferredAccount.withdraw(200)
transferredAccount.withdraw(200)
transferredAccount.deposit(500)
const transferredAccountWithBalanceCalculation = compose(withBalanceCalculation({}))(transferredAccount)
console.log(`${transferredAccountWithBalanceCalculation.name}: ${transferredAccountWithBalanceCalculation.calculateBalance()}`)
const openBankAccount = ({name = 'anonymous'}) => ({transactions = []}) => ({
name,
transactions,
deposit: amount => transactions.push({deposit: amount}),
withdraw: amount => transactions.push({withdraw: amount}),
})
const withBalanceCalculation = ({amount = 0}) => (obj = {}) => Object.assign(obj, {
calculateBalance: () => (obj.transactions || []).reduce((s, n) => {
if(n.deposit) s += n.deposit
if(n.withdraw) s -= n.withdraw
if(s < 0) s += n.withdraw
return s
}, amount),
})
const withStore = () => (obj = {}) => Object.assign(obj, {
load: data => JSON.parse(data),
save: () => JSON.stringify(obj),
})
// compose high-order functions
const compose = (...funcs) => funcs.reduce((a, b) => (...args) => a(b(...args)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment