Last active
May 10, 2018 20:57
-
-
Save PanAeon/db6bd5aac9c1a2c203df271484fd77b8 to your computer and use it in GitHub Desktop.
DSL.scala
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
package mydsl3 | |
// don't forgot DeepHLister... | |
import shapeless._, test._ | |
trait DeepHLister[R <: HList] extends DepFn1[R] { type Out <: HList } | |
trait LowPriorityDeepHLister { | |
type Aux[R <: HList, Out0 <: HList] = DeepHLister[R] { type Out = Out0 } | |
implicit def headNotCaseClassDeepHLister[H, T <: HList](implicit | |
dht: Lazy[DeepHLister[T]] | |
): Aux[H :: T, H :: dht.value.Out] = new DeepHLister[H :: T] { | |
type Out = H :: dht.value.Out | |
def apply(r: H :: T) = r.head :: dht.value(r.tail) | |
} | |
} | |
object DeepHLister extends LowPriorityDeepHLister { | |
implicit object hnilDeepHLister extends DeepHLister[HNil] { | |
type Out = HNil | |
def apply(r: HNil) = HNil | |
} | |
implicit def headCaseClassDeepHLister[H, R <: HList, T <: HList](implicit | |
gen: Generic.Aux[H, R], | |
dhh: Lazy[DeepHLister[R]], | |
dht: Lazy[DeepHLister[T]] | |
): Aux[H :: T, dhh.value.Out :: dht.value.Out] = new DeepHLister[H :: T] { | |
type Out = dhh.value.Out :: dht.value.Out | |
def apply(r: H :: T) = dhh.value(gen.to(r.head)) :: dht.value(r.tail) | |
} | |
def apply[R <: HList](implicit dh: DeepHLister[R]): Aux[R, dh.Out] = dh | |
} | |
object DeepHListerDemo extends App { | |
case class A(x: Int, y: String) | |
case class B(x: A, y: A) | |
case class C(b: B, a: A) | |
case class D(a: A, b: B) | |
type ARepr = Int :: String :: HNil | |
type BRepr = ARepr :: ARepr :: HNil | |
type CRepr = BRepr :: ARepr :: HNil | |
type DRepr = ARepr :: BRepr :: HNil | |
val adhl = DeepHLister[A :: HNil] | |
val x = A(3, "foo") | |
val x1 = adhl(x::HNil) | |
println(x1) | |
typed[DeepHLister.Aux[A :: HNil, ARepr :: HNil]](adhl) | |
val bdhl = DeepHLister[B :: HNil] | |
typed[DeepHLister.Aux[B :: HNil, BRepr :: HNil]](bdhl) | |
val cdhl = DeepHLister[C :: HNil] | |
typed[DeepHLister.Aux[C :: HNil, CRepr :: HNil]](cdhl) | |
val ddhl = DeepHLister[D :: HNil] | |
typed[DeepHLister.Aux[D :: HNil, DRepr :: HNil]](ddhl) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment