Skip to content

Instantly share code, notes, and snippets.

object MenuService {
def glutenFree[T](items: List[T])(implicit G: GlutenFree[T]): List[T] = {
items.filter(item => G.isGlutenFree(item))
}
}
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] {
scala> import OutsourcedPerishables._
import OutsourcedPerishables._
scala> DailyOrderService.needsReplacing(List(IceCream(), IceCream(), IceCream()))
res0: List[IceCream] = List(IceCream(), IceCream(), IceCream())
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 Perishables._
import Perishables._
scala> DailyOrderService.needsReplacing(List(Baguette(), Baguette(), Baguette()))
res0: List[Baguette] = List()
object DailyOrderService {
def needsReplacing[T](items: List[T])(implicit p: Perishable[T]): List[T] = {
items.filter(_.expired)
}
}
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
}
}
def needsReplacing[T](perishables: List[PerishableLike[T]]): List[PerishableLike[T]] = {
perishables.filter(_.expired)
}