Skip to content

Instantly share code, notes, and snippets.

@knutwalker
Created November 10, 2015 20:46
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 knutwalker/8b9b6f386c1699b18c2b to your computer and use it in GitHub Desktop.
Save knutwalker/8b9b6f386c1699b18c2b to your computer and use it in GitHub Desktop.
class CreditCard {
def charge(price: Double): Unit =
println(s"side effect ${##}")
}
case class Coffee(name: String = "Venti Tall Latte with Grande Soy Frappucino Whip Cream Extra Beans") {
def price: Double = 13.37
}
class Cafe {
def buyCoffee(cc: CreditCard): (Coffee, Charge) = {
val coffee = Coffee()
(coffee, Charge(cc, coffee.price))
}
def buyCoffees(cc: CreditCard, n: Int): (List[Coffee], Charge) = {
val (coffees, charges) = List.fill(n)(buyCoffee(cc)).unzip
(coffees, charges.foldLeft(Charge(cc, 0))(_ add _))
}
}
case class Charge(cc: CreditCard, amount: Double) {
def add(other: Charge) = {
require(cc == other.cc, "Can't combine to different cards.")
Charge(cc, amount + other.amount)
}
def charge(): Unit =
cc.charge(amount)
}
object cafe extends App {
val cafe = new Cafe
val (coffee, charge1) = cafe.buyCoffee(new CreditCard)
val (coffees, charge2) = cafe.buyCoffees(new CreditCard, 5)
println(s"coffees = ${coffee :: coffees}")
try {
val finalCharge = charge1 add charge2
finalCharge.charge()
} catch {
case ex: Throwable ⇒
println(s"ohoh: ${ex.getMessage}")
charge1.charge()
charge2.charge()
}
}
class Cafe {
def buyCoffee(cc: CreditCard): (Coffee, Charge[cc.type]) = {
val coffee = Coffee()
(coffee, Charge[cc.type](cc, coffee.price))
}
def buyCoffees(cc: CreditCard, n: Int): (List[Coffee], Charge[cc.type]) = {
val (coffees, charges) = List.fill(n)(buyCoffee(cc)).unzip
(coffees, charges.foldLeft(Charge[cc.type](cc, 0))(_ add _))
}
}
case class Charge[CC <: CreditCard](cc: CC, amount: Double) {
def add(other: Charge[CC]): Charge[CC] =
Charge(cc, amount + other.amount)
def charge(): Unit =
cc.charge(amount)
}
object cafe extends App {
val cafe = new Cafe
val (coffee, charge1) = cafe.buyCoffee(new CreditCard)
val (coffees, charge2) = cafe.buyCoffees(new CreditCard, 5)
println(s"coffees = ${coffee :: coffees}")
// compile error
// val finalCharge = charge1.add(charge2)
// finalCharge.charge()
charge1.charge()
charge2.charge()
// this works though
val cc = new CreditCard
val charge11 = cafe.buyCoffee(cc)._2
val charge12 = cafe.buyCoffees(cc, 5)._2
val finalCharge = charge11.add(charge12)
finalCharge.charge()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment