This file contains hidden or 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 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] { |
This file contains hidden or 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
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) | |
} |
This file contains hidden or 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
[error] ...could not find implicit value for parameter e: Price[Item] | |
[error] total + implicitly[Price[Item]].price(item) | |
[error] ^ |
This file contains hidden or 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
def orderTotal(shoppingCart: List[Item]): Double = { | |
shoppingCart.foldLeft(0.0) { case (total, item) => | |
total + implicitly[Price[Item]].price(item) | |
} | |
} |
This file contains hidden or 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
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] { |
This file contains hidden or 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
trait Price[A] { | |
def price(a: A): Double | |
} |
This file contains hidden or 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
sealed trait Hygiene extends Item | |
case class Shampoo(price: Double) extends Hygiene | |
case class ToothPaste(price: Double) extends Hygiene |
This file contains hidden or 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
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 |
This file contains hidden or 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
def dairyAndGlutenFree[T](items: List[T])(implicit D: DairyFree[T], G: GlutenFree[T]): List[T] = { | |
items.filter(item => D.isDairyFree(item) && G.isGlutenFree(item)) | |
} |
This file contains hidden or 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
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] { |