Skip to content

Instantly share code, notes, and snippets.

@apskii
Created November 22, 2014 01:24
Show Gist options
  • Save apskii/bb3a95d7407243a38daf to your computer and use it in GitHub Desktop.
Save apskii/bb3a95d7407243a38daf to your computer and use it in GitHub Desktop.
Subtyping recursive types
sealed trait Type {
override def equals(y: Any) = super.equals(y)
override def hashCode = super.hashCode
def isSubtypeOf(ty: Type): Boolean = {
def f(a: Type, b: Type, trail: Set[(Any, Any)]): Boolean =
if (trail contains (a, b))
true
else (a, b) match {
case (Bot, _) => true
case (_, Top) => true
case (Arr(d1, c1), Arr(d2, c2)) => f(d2, d1, trail) && f(c1, c2, trail)
case (Mu(t1), Mu(t2)) => f(t1, t2, trail + ((a, b)))
case (Mu(t), _) => f(t, b, trail + ((a, b)))
case (_, Mu(t)) => f(a, t, trail + ((a, b)))
case _ => false
}
f(this, ty, Set.empty)
}
}
case object Bot extends Type
case object Top extends Type
case class Arr(dom: Type, cod: Type) extends Type
case class Mu(var ty: Type) extends Type
object Type {
def mu(binder: Type => Type): Type = {
val knot: Mu = Mu(null)
knot.ty = binder(knot)
knot
}
}
object SRT extends scala.App {
import Type._
val a = mu { t => Arr(Arr(t, t), Bot) }
val b = mu { s => Arr(Arr(s, Bot), Top) }
println(a isSubtypeOf b)
val c = mu { t => Arr(Top, t) }
val d = mu { s => Arr(Bot, Arr(Bot, s)) }
println(c isSubtypeOf d)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment