Skip to content

Instantly share code, notes, and snippets.

@adilakhter
Last active May 24, 2017 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adilakhter/5b28036441d5245c2550919c85967ba9 to your computer and use it in GitHub Desktop.
Save adilakhter/5b28036441d5245c2550919c85967ba9 to your computer and use it in GitHub Desktop.
Shapeless : Checking of the Type Constraints of Polymorphic Functions (lifted types)
// details: https://stackoverflow.com/questions/44159203/shapeless-checking-of-the-type-constraints-of-polymorphic-functions-lifted-ty
import shapeless._
import ops.hlist._
import ops.function._
import syntax.std.function._
object ShapelessExample {
case class Place[A](a: A) extends AnyVal
implicit class Ops[P <: Product, L <: HList, U <: HList, C <: HList](p: P)(
implicit
val g: Generic.Aux[P, L],
val l: LiftAll.Aux[Unwrapped, L, U],
val c: Comapped.Aux[L, Place, C]) {
def ~|>[F, R](fn: F)(implicit fp: FnToProduct.Aux[F, C ⇒ R]) = {
def fuckitZip(l1: HList, l2: HList): HList = (l1, l2) match {
case (h1 :: t1, h2 :: t2) => (h1, h2) :: fuckitZip(t1, t2)
case _ => HNil
}
def fuckitMap(l: HList, f: Any => Any): HList = l match {
case HNil => HNil
case h :: t => f(h) :: fuckitMap(t, f)
}
def f(a: Any): Any = a match {
case (y: Any, x: Any) =>
x.asInstanceOf[Unwrapped[Any] {type U = Any}].unwrap(y)
}
val zp = fuckitZip(g.to(p), l.instances)
val uw = fuckitMap(zp, f _).asInstanceOf[C]
fn.toProduct(uw)
}
}
val p1 = Place(1)
val p2 = Place(2)
val res = (p1,p2, p2) ~|> ((x: Int, y: Int, z: Int) ⇒ x + y + z)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment