Skip to content

Instantly share code, notes, and snippets.

@HerringtonDarkholme
Created November 18, 2014 00:07
Show Gist options
  • Select an option

  • Save HerringtonDarkholme/9fe79f235e38e635c75d to your computer and use it in GitHub Desktop.

Select an option

Save HerringtonDarkholme/9fe79f235e38e635c75d to your computer and use it in GitHub Desktop.
Type Level Template
trait Tag
class Concat[A <: Tag, B <: Tag](a: A, b: B) extends Tag
trait NestTag[A <: Tag] extends Tag {
val child: A
}
trait Inline extends Tag
trait Block extends Tag
case class div[T <: Tag](t :T = null) extends NestTag[T] with Block {
val child = t
}
case class p[T <: Tag](t :T = null) extends NestTag[T] with Block {
val child = t
}
case class a[T <: Inline](t :T = null) extends NestTag[T] with Inline {
val child = t
}
implicit class PlusTag[A <: Tag](a: A) {
def +[B <: Tag](b: B) = new Concat(a, b)
}
trait Contains[A <: Tag, C[_ <: Tag] <: NestTag[_], T[_ <: Tag] <: NestTag[_]] {
type D <: Tag
def extract(k: C[A]): T[D]
}
case class jQ[A <: Tag, C[_ <: Tag] <: NestTag[_]](c: C[A]) {
def has[T[_ <: Tag] <: NestTag[_]](implicit ev: Contains[A, C, T]) = ev.extract(c)
}
trait LowPriorityImplicit {
implicit def htmlEq[A <: Tag, C[_ <: Tag] <: NestTag[_], T[_ <: Tag] <: NestTag[_]](implicit ev: C[A] =:= T[A]) =
new Contains[A, C, T] {
type D = A
def extract(k: C[A]): T[D] = k
}
}
object Test extends LowPriorityImplicit {
implicit def recurEq[A <: Tag, B[_ <: Tag] <: NestTag[_], C[_ <: Tag] <: NestTag[_], T[_ <: Tag] <: NestTag[_]]
(implicit ev: Contains[A, B, T]) = new Contains[B[A], C, T] {
type D = ev.D
def extract(k: C[B[A]]): T[D] = ev.extract(k.child.asInstanceOf[B[A]])
}
val k = div(
p(
div(
p(a())
)
)
)
val r = jQ(k).has[p]
println(r)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment