Skip to content

Instantly share code, notes, and snippets.

object Perishables {
implicit val baguettePerishable: Perishable[Baguette] = new Perishable[Baguette] {
def expired(b: Baguette): Boolean = false // hard coded, in reality we would examine `b` to figure out if it expired
}
implicit val croissantPerishable: Perishable[Croissant] = new Perishable[Croissant] {
def expired(c: Croissant): Boolean = false
}
}
object DailyOrderService {
def needsReplacing[T](items: List[T])(implicit p: Perishable[T]): List[T] = {
items.filter(_.expired)
}
}
scala> import Perishables._
import Perishables._
scala> DailyOrderService.needsReplacing(List(Baguette(), Baguette(), Baguette()))
res0: List[Baguette] = List()
object OutsourcedPerishables {
implicit val iceCreamPerishable: Perishable[IceCream] = new Perishable[IceCream] {
def expired(i: IceCream): Boolean = true // in reality you would actually calculate the expiration for ice cream
}
}
scala> import OutsourcedPerishables._
import OutsourcedPerishables._
scala> DailyOrderService.needsReplacing(List(IceCream(), IceCream(), IceCream()))
res0: List[IceCream] = List(IceCream(), IceCream(), IceCream())
trait GlutenFree[T] {
def isGlutenFree(item: T): Boolean
}
object GlutenFree {
implicit val baguetteGlutenFree: GlutenFree[Baguette] = new GlutenFree[Baguette] {
def isGlutenFree(b: Baguette): Boolean = true
}
implicit val croissantGlutenFree: GlutenFree[Croissant] = new GlutenFree[Croissant] {
object MenuService {
def glutenFree[T](items: List[T])(implicit G: GlutenFree[T]): List[T] = {
items.filter(item => G.isGlutenFree(item))
}
}
trait DairyFree[T] {
def isDairyFree(item: T): Boolean
}
object DairyFree {
implicit val baguetteDairyFree: DairyFree[Baguette] = new DairyFree[Baguette] {
def isDairyFree(b: Baguette): Boolean = true
}
implicit val croissantDairyFree: DairyFree[Croissant] = new DairyFree[Croissant] {
def dairyAndGlutenFree[T](items: List[T])(implicit D: DairyFree[T], G: GlutenFree[T]): List[T] = {
items.filter(item => D.isDairyFree(item) && G.isGlutenFree(item))
}
sealed trait Item
sealed trait Food extends Item
sealed trait Bread extends Food
case class Cake(price: Double) extends Bread
case class Baguette(price: Double) extends Bread
sealed trait Fruit extends Food
case class Apple(weightLbs: Double) extends Fruit