Skip to content

Instantly share code, notes, and snippets.

import shapeless._
object PriceCompanion extends LabelledTypeClassCompanion[Price] {
object typeClass extends LabelledTypeClass[Price] {
def emptyProduct: Price[HNil] = new Price[HNil] {
def price(t: HNil) = 0.0
}
def product[F, T <: HList](name: String, sh: Price[F], st: Price[T]): Price[F :: T] = new Price[F :: T] {
object Item {
implicit val price: Price[Item] = new Price[Item] {
def price(item: Item): Double = item match {
case cake: Cake => Cake.price.price(cake)
case baguette: Baguette => Baguette.price.price(baguette)
case apple: Apple => Apple.price.price(apple)
case orange: Orange => Orange.price.price(orange)
case shampoo: Shampoo => Shampoo.price.price(shampoo)
case toothPaste: ToothPaste => ToothPaste.price.price(toothPaste)
}
[error] ...could not find implicit value for parameter e: Price[Item]
[error] total + implicitly[Price[Item]].price(item)
[error] ^
def orderTotal(shoppingCart: List[Item]): Double = {
shoppingCart.foldLeft(0.0) { case (total, item) =>
total + implicitly[Price[Item]].price(item)
}
}
object Cake {
implicit val price: Price[Cake] = new Price[Cake] {
def price(cake: Cake): Double = cake.price
}
}
object Apple {
val PricePerLb: Double = 3.0
implicit val price: Price[Apple] = new Price[Apple] {
sealed trait Hygiene extends Item
case class Shampoo(price: Double) extends Hygiene
case class ToothPaste(price: Double) extends Hygiene
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
def dairyAndGlutenFree[T](items: List[T])(implicit D: DairyFree[T], G: GlutenFree[T]): List[T] = {
items.filter(item => D.isDairyFree(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] {