Skip to content

Instantly share code, notes, and snippets.

@alexarchambault
Last active August 29, 2015 14:12
Show Gist options
  • Save alexarchambault/86de91eb158c5f485522 to your computer and use it in GitHub Desktop.
Save alexarchambault/86de91eb158c5f485522 to your computer and use it in GitHub Desktop.
Lazy & case object constructors
sealed trait Base0
case class Foo0() extends Base0
case class Bar0() extends Base0
sealed trait Base1
case object Foo1 extends Base1
case object Bar1 extends Base1
object Base {
Generic[Foo0]
Generic[Bar0]
val g0 = Generic[Base0]
implicitly[g0.Repr =:= (Bar0 :+: Foo0 :+: CNil)]
TC[Foo0]
TC[Bar0]
TC[Base0] // Works with case class constructors
Generic[Foo1.type]
Generic[Bar1.type]
val g1 = Generic[Base1]
implicitly[g1.Repr =:= (Bar1.type :+: Foo1.type :+: CNil)]
TC[Foo1.type]
TC[Bar1.type]
TC[Base1] // This one (case object constructors) doesn't compile
}
trait TC[T] {
def apply(t: T): String
}
object TC {
def apply[T](implicit tc: TC[T]): TC[T] = tc
implicit def hnilTC: TC[HNil] =
new TC[HNil] {
def apply(l: HNil) = "HNil"
}
implicit def hconsTC[H, T <: HList](implicit
headTC: Lazy[TC[H]],
tailTC: Lazy[TC[T]]
): TC[H :: T] =
new TC[H :: T] {
def apply(l: H :: T) = s"${headTC.value(l.head)} :: ${tailTC.value(l.tail)}"
}
implicit def cnilTC: TC[CNil] =
new TC[CNil] {
def apply(l: CNil) = "CNil"
}
implicit def cconsTC[H, T <: Coproduct](implicit
headTC: Lazy[TC[H]],
tailTC: Lazy[TC[T]]
): TC[H :+: T] =
new TC[H :+: T] {
def apply(l: H :+: T) = l match {
case Inl(h) =>
headTC.value(h)
case Inr(t) =>
tailTC.value(t)
}
}
implicit def projectTC[F, G](implicit
gen: Generic.Aux[F, G],
tc: Lazy[TC[G]]
): TC[F] =
new TC[F] {
def apply(f: F) = tc.value(gen.to(f))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment