Skip to content

Instantly share code, notes, and snippets.

@lu4nm3
Created May 16, 2020 20:00
Show Gist options
  • Save lu4nm3/a064a3baf3ff8c75b126c4e6bc38daae to your computer and use it in GitHub Desktop.
Save lu4nm3/a064a3baf3ff8c75b126c4e6bc38daae to your computer and use it in GitHub Desktop.
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] {
def price(ft: F :: T): Double = {
sh.price(ft.head) + st.price(ft.tail)
}
}
def emptyCoproduct: Price[CNil] = new Price[CNil] {
def price(t: CNil): Double = 0.0
}
def coproduct[L, R <: Coproduct](name: String, rl: => Price[L], rr: => Price[R]): Price[L :+: R] = new Price[L :+: R] {
def price(lr: L :+: R): Double = lr match {
case Inl(l) => rl.price(l)
case Inr(r) => rr.price(r)
}
}
def project[F, G](instance: => Price[G], to: F => G, from: G => F): Price[F] = new Price[F] {
def price(f: F): Double = {
instance.price(to(f))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment