Last active
March 15, 2017 22:53
-
-
Save tomverran/f3153911961c03c0610a0e3fc0d2a937 to your computer and use it in GitHub Desktop.
A typeclass to recursively turn case classes into labelled nested HLists
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.labelled._ | |
trait DeepGeneric[T] { | |
type Repr <: HList | |
def to(t: T): Repr | |
} | |
trait LowPriority { | |
implicit def plainHconsDeepGeneric[H, T <: HList]( | |
implicit | |
tl: DeepGeneric[T] | |
) = new DeepGeneric[H :: T] { | |
def to(t: H :: T): Repr = t.head :: tl.to(t.tail) | |
type Repr = H :: tl.Repr | |
} | |
} | |
object DeepGeneric extends LowPriority { | |
type Aux[A, R] = DeepGeneric[A] { type Repr = R } | |
def apply[A : DeepGeneric]: DeepGeneric[A] = implicitly[DeepGeneric[A]] | |
implicit val hnilDeepGeneric = new DeepGeneric[HNil] { | |
def to(a: HNil) = a | |
type Repr = HNil | |
} | |
implicit def nestedHconsDeepGeneric[K, H, T <: HList, RH <: HList, RT <: HList]( | |
implicit | |
dg: Lazy[DeepGeneric.Aux[H, RH]], | |
tl: Lazy[DeepGeneric.Aux[T, RT]] | |
) = new DeepGeneric[FieldType[K, H] :: T] { | |
type Repr = FieldType[K, RH] :: RT | |
def to(t: FieldType[K, H] :: T): Repr = { | |
labelled.field[K](dg.value.to(t.head)) :: tl.value.to(t.tail) | |
} | |
} | |
implicit def genericDeepGeneric[A, R <: HList]( | |
implicit | |
g: LabelledGeneric.Aux[A, R], | |
d: DeepGeneric[R] | |
) = new DeepGeneric[A] { | |
def to(a: A) = d.to(g.to(a)) | |
type Repr = d.Repr | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment