Created
November 17, 2017 04:33
-
-
Save fehu/ace5d384e07d5600cce9f4f3bdb5b73f to your computer and use it in GitHub Desktop.
Scala - shapeless - CovUnliftFilter
This file contains hidden or 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 scala.language.higherKinds | |
import shapeless._ | |
import shapeless.ops.hlist.IsHCons | |
/** | |
* Type class supporting access to all the elements of this `HList`, that are lifted sub-types of `U`. | |
* Selects all {{{ F[A] }}}, contained in the list `L`, such that {{{ A <: U }}}. | |
*/ | |
trait CovUnliftFilter[L <: HList, F[_], U] extends DepFn1[L] with Serializable { type Out <: HList } | |
object CovUnliftFilter { | |
def apply[L <: HList, F[_], U](implicit filter: CovUnliftFilter[L, F, U]): Aux[L, F, U, filter.Out] = filter | |
type Aux[L <: HList, F[_], U, Out0 <: HList] = CovUnliftFilter[L, F, U] { type Out = Out0 } | |
implicit def take[L <: HList, F[_], U, FH, H, T <: HList]( | |
implicit | |
cons: IsHCons.Aux[L, FH, T], ev0: FH <:< F[H], ev: H <:< U, next: CovUnliftFilter[T, F, U] | |
): CovUnliftFilter[L, F, U] = new CovUnliftFilter[L, F, U]{ | |
type Out = FH :: next.Out | |
def apply(t: L): FH :: next.Out = cons.head(t) :: next(cons.tail(t)) | |
} | |
implicit def drop[L <: HList, F[_], U, FH, H, T <: HList]( | |
implicit | |
cons: IsHCons.Aux[L, FH, T], ev0: FH <:< F[H], ev: H <:!< U, next: CovUnliftFilter[T, F, U] | |
): CovUnliftFilter[L, F, U] = new CovUnliftFilter[L, F, U]{ | |
type Out = next.Out | |
def apply(t: L): next.Out = next(cons.tail(t)) | |
} | |
implicit def nil[F[_], U]: CovUnliftFilter[HNil, F, U] = Nil.asInstanceOf[CovUnliftFilter[HNil, F, U]] | |
private object Nil extends CovUnliftFilter[HNil, Id, Any]{ | |
type Out = HNil | |
def apply(t: HNil): HNil = HNil | |
} | |
} | |
/** | |
* Type class witnessing that `L` contains at least one element, satisfying corresponding filter conditions. | |
*/ | |
trait CovUnliftFilteredNonempty[L <: HList, F[_], U] | |
object CovUnliftFilteredNonempty{ | |
implicit def evidence[L <: HList, F[_], U, L0 <: HList]( | |
implicit | |
filter: CovUnliftFilter.Aux[L, F, U, L0], cons: IsHCons[L0] | |
): CovUnliftFilteredNonempty[L, F, U] = Evidence.asInstanceOf[CovUnliftFilteredNonempty[L, F, U]] | |
private object Evidence extends CovUnliftFilteredNonempty[HList, Id, Any] | |
} |
This file contains hidden or 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 scala.language.higherKinds | |
import shapeless.{HList, Id} | |
import shapeless.ops.hlist.LiftAll | |
package object hlist { | |
/** Alias for [[CovUnliftFilter]] when `HList`'s elements are not lifted. */ | |
type CovFilter[L <: HList, U] = CovUnliftFilter[L, Id, U] | |
object CovFilter { | |
def apply[L <: HList, U](implicit filter: CovFilter[L, U]): Aux[L, U, filter.Out] = filter | |
type Aux[L <: HList, U, Out0 <: HList] = CovFilter[L, U] {type Out = Out0} | |
} | |
/** Alias for [[CovUnliftFilteredNonempty]] when `HList`'s elements are not lifted. */ | |
type CovFilteredNonempty[L <: HList, U] = CovUnliftFilteredNonempty[L, Id, U] | |
/** An alias for [[LiftAll]] `apply`, that preserves type refinement of lifted instances. */ | |
object LiftAllInstances{ | |
def apply[F[_], In <: HList](implicit ev: LiftAll[F, In]): ev.Out = ev.instances | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment