Created
April 27, 2015 21:04
-
-
Save kim0/7d7d86656081f2452d42 to your computer and use it in GitHub Desktop.
Scala futures example, coffee brewing
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._ | |
import scala.concurrent.duration._ | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scala.concurrent.duration._ | |
import scala.util.Random | |
import scala.util.Try | |
object kitchen extends App { | |
///////////////////////////// | |
// Some type aliases, just for getting more meaningful method signatures: | |
type CoffeeBeans = String | |
type GroundCoffee = String | |
case class Water(temperature: Int) | |
type Milk = String | |
type FrothedMilk = String | |
type Espresso = String | |
type Cappuccino = String | |
// some exceptions for things that might go wrong in the individual steps | |
// (we'll need some of them later, use the others when experimenting | |
// with the code): | |
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("start grinding...") | |
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 the water now") | |
Thread.sleep(Random.nextInt(2000)) | |
println("hot, it's hot!") | |
water.copy(temperature = 85) | |
} | |
def frothMilk(milk: Milk): Future[FrothedMilk] = Future { | |
println("milk frothing system engaged!") | |
Thread.sleep(Random.nextInt(2000)) | |
println("shutting down milk frothing system") | |
s"frothed $milk" | |
} | |
def brew(coffee: GroundCoffee, heatedWater: Water): Future[Espresso] = Future { | |
println("happy brewing :)") | |
Thread.sleep(Random.nextInt(2000)) | |
println("it's brewed!") | |
"espresso" | |
} | |
///////////// Business logic | |
println("Kitched starting") | |
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) | |
} | |
val capo = prepareCappuccino() | |
Await.ready(capo, 1 minutes) | |
println("Kitched ending") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment