const Box = x =>
({
map: f => Box(f(x)),
chain: f => f(x),
fold: f => f(x),
toString: () => `Box(${x})`
})
// Exercise: Box
// Goal: Refactor each example using Box
// Keep these tests passing!
// Bonus points: no curly braces
// Ex1: Using Box, refactor moneyToFloat to be unnested.
// =========================
const _moneyToFloat = str =>
parseFloat(str.replace(/\$/, ''))
const moneyToFloat = str => Box(str)
.map(str => str.replace(/\$/, ''))
.fold(parseFloat)
QUnit.test("Ex1: moneyToFloat", assert => {
assert.equal(String(moneyToFloat('$5.00')), 5)
})
// Ex2: Using Box, refactor percentToFloat to remove assignment
// =========================
const _percentToFloat = str => {
const float = parseFloat(str.replace(/\%/, ''))
return float * 0.0100
}
const percentToFloat = str => Box(str)
.map(str => str.replace(/\%/, ''))
.map(parseFloat)
.fold(float => float * 0.0100)
QUnit.test("Ex2: percentToFloat", assert => {
assert.equal(String(percentToFloat('20%')), 0.2)
})
// Ex3: Using Box, refactor applyDiscount (hint: each variable introduces a new Box)
// =========================
const __applyDiscount = (price, discount) => {
const cents = moneyToFloat(price)
const savings = percentToFloat(discount)
return cents - (cents * savings)
}
const _applyDiscount = (price, discount) =>
Box(moneyToFloat(price))
.fold(cents => Box(percentToFloat(discount))
.fold(savings => cents - (cents * savings)))
const applyDiscount = (price, discount) =>
Box(moneyToFloat(price))
.chain(cents => Box(percentToFloat(discount))
.fold(savings => cents - (cents * savings)))
QUnit.test("Ex3: Apply discount", assert => {
assert.equal(String(applyDiscount('$5.00', '20%')), 4)
})