Long Cao
Software Engineer @ MediaMath
class Coffee
def buyCoffee(money: Int): Coffee = {
if (money < 3)
throw new Exception(s"not enough money, need 3 dollars")
else
new Coffee
}
class Coffee
// Not referentially transparent:
// Does this function always return a Coffee if it throws an exception?
def buyCoffee(money: Int): Coffee
def buyCoffee(money: Int): Option[Coffee] = {
if (money < 3)
None
else
Some(new Coffee)
}
scala> buyCoffee(2).flatMap(_ => Some("i got a coffee"))
res0: Option[String] = None
scala> buyCoffee(3).flatMap(_ => Some("i got a coffee"))
res2: Option[String] = Some(i got a coffee)
import scala.util.{ Failure, Success, Try }
def buyCoffee(money: Int): Try[Coffee] = {
Try {
if (money < 3)
throw new Exception(s"not enough money, need 3 dollars")
else
new Coffee
}
}
scala> buyCoffee(2)
res0: scala.util.Try[Coffee] =
Failure(java.lang.Exception: not enough money, need 3 dollars)
scala> buyCoffee(3)
res1: scala.util.Try[Coffee] = Success(Coffee@5e7cd6cc)
case class FailureReason(reason: String)
def buyCoffee(money: Int): Either[FailureReason, Coffee] = {
if (money < 3)
Left(FailureReason(s"not enough money, need 3 dollars"))
else
Right(new Coffee)
}
scala> buyCoffee(2)
res0: scala.util.Either[FailureReason,Coffee] =
Left(FailureReason(not enough money, need 3))
scala> buyCoffee(3)
res1: scala.util.Either[FailureReason,Coffee] =
Right(Coffee@2a8448fa)
import org.scalactic.{ Bad, Good, Or }
object CoffeeServiceOr {
def purchaseCoffee(money: Int): Coffee Or FailureReason =
for {
beans <- buyBeans(money)
coffee <- brewCoffee(beans)
} yield coffee
// fails without enough money
def buyBeans(money: Int): Beans Or FailureReason = { ... }
// fails 25% of the time to simulate a faulty grinder
def brewCoffee(beans: Beans): Coffee Or FailureReason = { ... }
}
scala> CoffeeServiceOr.purchaseCoffee(2)
res0: org.scalactic.Or[Coffee,FailureReason] =
Bad(FailureReason(Not enough money to buy beans for a coffee, need 3))
scala> CoffeeServiceOr.purchaseCoffee(3)
res1: org.scalactic.Or[Coffee,FailureReason] =
Bad(FailureReason(Faulty grinder failed to grind beans!))