Skip to content

Instantly share code, notes, and snippets.

@pyetras
Created April 21, 2015 13:34
Show Gist options
  • Save pyetras/b782801e49c3d48fce10 to your computer and use it in GitHub Desktop.
Save pyetras/b782801e49c3d48fce10 to your computer and use it in GitHub Desktop.
Lift or unlift type from shapeless' hlist element type
object UnliftType {
def apply[L <: HList, M[_]](implicit unlift: UnliftType[L, M]) = unlift
type Aux[L <: HList, M[_], R <: HList] = UnliftType[L, M] { type Out = R }
implicit def unliftType[H, L <: HList, R <: HList, M[_]]
(implicit ev: Aux[L, M, R]) :
Aux[M[H] :: L, M, H :: R] =
new UnliftType[M[H] :: L, M] { type Out = H :: R }
implicit def unliftNoType[H, L <: HList, R <: HList, M[_]]
(implicit ev: Aux[L, M, R], e: H =:!= M[T] forSome { type T }) :
Aux[H :: L, M, H :: R] =
new UnliftType[H :: L, M] { type Out = H :: R }
implicit def unliftNil[M[_]]: Aux[HNil, M, HNil] =
new UnliftType[HNil, M] { type Out = HNil }
}
trait LiftType[-L <: HList, M[_]] {
type Out <: HList
}
object LiftType {
type Aux[L <: HList, M[_], R <: HList] = LiftType[L, M] { type Out = R }
def apply[L <: HList, M[_]](implicit lift: LiftType[L, M]) = lift
implicit def liftType[H, L <: HList, R <: HList, M[_]]
(implicit ev: Aux[L, M, R], ev2: H =:!= M[T] forSome { type T }):
Aux[H::L, M, M[H] :: R] =
new LiftType[H :: L, M] { type Out = M[H] :: R}
implicit def liftNil[M[_]]: Aux[HNil, M, HNil] = new LiftType[HNil, M] { type Out = HNil }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment