Created
February 2, 2015 18:09
-
-
Save betandr/4aaad0ab750ea46ece9e to your computer and use it in GitHub Desktop.
CoffeeMachine.scala
This file contains 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
import scala.concurrent.future | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scala.concurrent.duration._ | |
import scala.util.Random | |
import scala.util.{Success, Failure} | |
class CoffeeMachine { | |
type CoffeeBeans = String | |
type GroundCoffee = String | |
case class Water(temperature: Int) | |
type Milk = String | |
type FrothedMilk = String | |
type Espresso = String | |
type Cappuccino = String | |
case class GrindingException(msg: String) extends Exception(msg) | |
case class FrothingException(msg: String) extends Exception(msg) | |
case class WaterBoilingException(msg: String) extends Exception(msg) | |
case class BrewingException(msg: String) extends Exception(msg) | |
def combine(espresso: Espresso, frothedMilk: FrothedMilk): Cappuccino = "cappuccino" | |
def grind(beans: CoffeeBeans): Future[GroundCoffee] = Future { | |
println(s"grinding '$beans'...") | |
Thread.sleep(Random.nextInt(2000)) | |
if (beans == "baked beans") throw GrindingException("are you joking?") | |
println("finished grinding...") | |
s"ground coffee of $beans" | |
} | |
def heatWater(water: Water): Future[Water] = Future { | |
println("heating water...") | |
Thread.sleep(Random.nextInt(2000)) | |
println("it's hot!") | |
water.copy(temperature = 85) | |
} | |
def frothMilk(milk: Milk): Future[FrothedMilk] = Future { | |
println(s"frothing $milk...") | |
Thread.sleep(Random.nextInt(2000)) | |
//if (milk contains "milk") throw FrothingException(s"you can only froth types of milk, not $milk")*/ | |
println("shutting down milk frother") | |
s"frothed $milk" | |
} | |
def brew(coffee: GroundCoffee, heatedWater: Water): Future[Espresso] = Future { | |
println(s"brewing $coffee") | |
Thread.sleep(Random.nextInt(2000)) | |
println("it's brewed!") | |
"espresso" | |
} | |
def prepareCappuccinoSequentially(): Future[Cappuccino] = { | |
for { | |
ground <- grind("arabica beans") | |
water <- heatWater(Water(20)) | |
foam <- frothMilk("milk") | |
espresso <- brew(ground, water) | |
} yield combine(espresso, foam) | |
} | |
def prepareCappuccino(): Future[Cappuccino] = { | |
val groundCoffee = grind("arabica beans") | |
val heatedWater = heatWater(Water(20)) | |
val frothedMilk = frothMilk("milk") | |
for { | |
ground <- groundCoffee | |
water <- heatedWater | |
foam <- frothedMilk | |
espresso <- brew(ground, water) | |
} yield combine(espresso, foam) | |
} | |
} | |
object CoffeeMachine extends App { | |
val maker = new CoffeeMachine | |
var start = System.currentTimeMillis() | |
maker.prepareCappuccino.onComplete { | |
case Success(coffee) => { | |
val end = System.currentTimeMillis() | |
println(s"You got $coffee in " + (end - start) + " ms") | |
} | |
case Failure(ex) => println(ex) | |
} | |
start = System.currentTimeMillis() | |
maker.prepareCappuccinoSequentially.onComplete { | |
case Success(coffee) => { | |
val end = System.currentTimeMillis() | |
println(s"You got $coffee in " + (end - start) + " ms") | |
} | |
case Failure(ex) => println(ex) | |
} | |
Thread.sleep(20000) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment