Created
September 15, 2016 04:24
-
-
Save n4to4/eb24e3bdeea9edafcbefbbdc80c13f0d to your computer and use it in GitHub Desktop.
This file contains 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._ | |
import shapeless.test._ | |
trait Weight[A] { def apply(a: A): Int } | |
object Weight { | |
def apply[A](f: A => Int) = new Weight[A] { def apply(a: A) = f(a) } | |
} | |
case class Foo(i: Int, s: String) | |
sealed trait Root | |
case class Bar(i: Int) extends Root | |
case class Baz(s: String) extends Root | |
object Base { | |
implicit val stringWeight: Weight[String] = Weight(_.size) | |
implicit def intWeight: Weight[Int] = Weight(identity) | |
} | |
object Product { | |
object WeightHelper extends ProductTypeClassCompanion[Weight] { | |
object typeClass extends ProductTypeClass[Weight] { | |
def emptyProduct: Weight[HNil] = Weight(_ => 0) | |
def product[H, T <: HList](hw: Weight[H], tw: Weight[T]): Weight[H :: T] = | |
Weight { case (h :: t) => hw(h) + tw(t) } | |
def project[F, G](w: => Weight[G], to: F => G,from: G => F): Weight[F] = | |
Weight(f => w(to(f))) | |
} | |
} | |
import Base._ | |
import WeightHelper._ | |
implicitly[Weight[Foo]] | |
implicitly[Weight[Bar]] | |
implicitly[Weight[Baz]] | |
illTyped("implicitly[Weight[Root]]") | |
} | |
object TC { | |
object WeightTypeClass extends TypeClassCompanion[Weight] { | |
object typeClass extends TypeClass[Weight] { | |
def emptyProduct: Weight[HNil] = Weight(_ => 0) | |
def product[H, T <: HList](hw: Weight[H], tw: Weight[T]): Weight[H :: T] = | |
Weight { case (h :: t) => hw(h) + tw(t) } | |
def project[F, G](w: => Weight[G], to: F => G, from: G => F): Weight[F] = | |
Weight(f => w(to(f))) | |
def emptyCoproduct: Weight[CNil] = Weight(_ => 0) | |
def coproduct[L, R <: Coproduct] | |
(lw: => Weight[L], rw: => Weight[R]): Weight[L :+: R] = Weight { | |
case Inl(h) => lw(h) | |
case Inr(t) => rw(t) | |
} | |
} | |
} | |
import Base._ | |
import WeightTypeClass._ | |
implicitly[Weight[Root]] | |
} | |
object Main extends App { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment