Skip to content

Instantly share code, notes, and snippets.

@joprice
Created May 23, 2016 19:50
Show Gist options
  • Save joprice/7c545d6e150f4f5143cf50a7af57ea50 to your computer and use it in GitHub Desktop.
Save joprice/7c545d6e150f4f5143cf50a7af57ea50 to your computer and use it in GitHub Desktop.
def path[A, B <: AnyRef](name: String, value: A, parent: B): FieldType[(name.type, parent.type), A] =
field[(name.type, parent.type)].apply[A](value)
def emptyPath[A](value: A): FieldType[Nothing, A] = field[Nothing](value)
trait Path[A] {
type Out <: HList
val value: Out
}
trait LowPriorityPath {
type Aux[A, B] = Path[A] {
type Out = B
}
implicit def nilPath[V]: Aux[FieldType[Nothing, V], HNil] = new Path[FieldType[Nothing, V]] {
type Out = HNil
val value = HNil
}
}
object Path extends LowPriorityPath {
implicit def consPath[A <: String, K, V <: AnyRef](
implicit
w: Witness.Aux[A],
rest: Path[V]
): Aux[FieldType[(w.T, K), V], A :: rest.Out] = new Path[FieldType[(w.T, K), V]] {
type Out = w.T :: rest.Out
val value = w.value :: rest.value
}
def apply[A <: AnyRef](a: A)(implicit p: Path[A]): p.Out = p.value
}
object Z
object Y {
def z = path("z", Z, this)
}
object X {
def y = path("y", Y, this)
}
val x = emptyPath(X)
val v = x.y.z
val result = Path(v)
result: Witness.`"z"`.T :: Witness.`"y"`.T :: HNil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment