Skip to content

Instantly share code, notes, and snippets.

@teldosas
Created January 12, 2017 10:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teldosas/f1db512fbf505165fd247f8be8bcb595 to your computer and use it in GitHub Desktop.
Save teldosas/f1db512fbf505165fd247f8be8bcb595 to your computer and use it in GitHub Desktop.
Class for generating generic representations of nested case classes
import shapeless._
trait GenericNested[P] {
type Repr
def to(p: P): Repr
def from(o: Repr): P
}
class LowPriorityNested {
type Aux[P, Repr0] = GenericNested[P] { type Repr = Repr0 }
implicit def base[T] = new GenericNested[T] {
type Repr = T
def to(t: T) = t
def from(t: T) = t
}
}
object GenericNested extends LowPriorityNested {
def apply[P](implicit g: GenericNested[P]): GenericNested.Aux[P, g.Repr] = g
implicit def hNil = new GenericNested[HNil] {
type Repr = HNil
def to(t: HNil) = t
def from(p: HNil) = p
}
implicit def hCons[H, H2, T <: HList, T2 <: HList](implicit gh: GenericNested.Aux[H,H2], gt: GenericNested.Aux[T, T2]) = new GenericNested[H::T] {
type Repr = H2::T2
def to(l: H::T) = {
val h::t = l
gh.to(h)::gt.to(t)
}
def from(l: H2::T2) = {
val h::t = l
gh.from(h)::gt.from(t)
}
}
implicit def prod[P <: Product, Repr, L](implicit g: Generic.Aux[P, Repr], gn: GenericNested.Aux[Repr,L]) = new GenericNested[P] {
type Repr = L
def to(p: P) = gn.to(g.to(p))
def from(l: L) = {
g.from(gn.from(l))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment