You have a restaurant, and a menu with a few drinks. Once a customer wants to leave you need to calculate the total price of all the drinks and print a receipt.
struct Drink {
let name: String, price: Int
}
struct Checkout {
let drinks: [Drink]
func add(drink: Drink, count : Int = 1) -> Checkout {
return Checkout(drinks: drinks + [Drink](count: count, repeatedValue: drink))
}
var total: Int {
return drinks.map { $0.price } .reduce(0, combine: +)
}
}
let menu = (
beer: Drink(name: "Schneider Weisse", price: 350),
mate: Drink(name: "Club Mate", price: 250),
coke: Drink(name: "Fritz Cola", price: 270)
)
First you create a receipt writer that will write a checkout you will build to a String:
typealias ReceiptWriter = Writer<String, Checkout>
let pure = ReceiptWriter.pure
let tell = ReceiptWriter.tell
Then you start by defiing a function to add a drink to a checkout and write the line in the receipt
func addDrink(drink: Drink, count : Int = 1)(checkout: Checkout) -> ReceiptWriter {
return Writer(checkout.add(drink, count: count), "\(drink.name) ⨉ \(count): \(drink.price * count)\n")
}
All that is left to do is write the whole receipt step by step:
let newCheckout = Checkout(drinks: [])
let writer = pure(newCheckout)
>>= tell("17 May, 2015\n")
>>= tell("\n")
>>= tell("🍺 Alcoholic drinks\n")
>>= addDrink(menu.beer, count: 3)
>>= tell("\n")
>>= tell("☕️ Non-alcoholic drinks\n")
>>= addDrink(menu.mate)
>>= addDrink(menu.coke)
>>= tell("\n")
>>= tell("Thank you for your visit...\n")
let (checkout, receipt) = writer.run()
checkout.total # => 1570
receipt # =>
# 17 May, 2015
# 🍺 Alcoholic drinks
# Schneider Weisse ⨉ 3: 1050
#
# ☕️ Non-alcoholic drinks
# Club Mate ⨉ 1: 250
# Fritz Cola ⨉ 1: 270
#
# Thank you for your visit...
Beautiful. Everything is pure and immutable.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request