Skip to content

Instantly share code, notes, and snippets.

@hobwekiva
Last active July 14, 2020 08:45
Show Gist options
  • Save hobwekiva/a4401807911423274a201b8a3f21099c to your computer and use it in GitHub Desktop.
Save hobwekiva/a4401807911423274a201b8a3f21099c to your computer and use it in GitHub Desktop.
// This sums up my understanding of
// https://github.com/lampepfl/dotty/issues/9359
// and https://github.com/lampepfl/dotty/issues/8430
// == on AnyVal does not imply singleton type equality
class Test[A](val x: Int) extends AnyVal
def coerce1[A, B](a: A): B = {
val x = new Test[A](1)
val y = new Test[B](1)
x match {
case _: y.type => a
}
}
// == on Any does not imply singleton type equality
def coerce2[A, B](a: A): B = {
// Any partiality can be fixed by using Option[B]
// and doing foreach(b => ...) at the callsite.
case class Key[X]()(val value: A => Either[X, A])
def foo[K[_], A, B](k0: K[A], k1: K[B]): k1.type = k0 match {
case k: k1.type => k
}
val k0 = Key[A]()((a: A) => Left(a))
val k1 = Key[B]()((a: A) => Right(a))
foo(k0, k1).value(a) match {
case Left(a) => a
}
}
// eq on AnyRef does not imply singleton type equality (assuming stdlib)
def coerce3[A, B]: A => B = {
val a = implicitly[A =:= A]
implicitly[B =:= B] match {
case _: a.type => implicitly[A =:= B]
}
}
object Test {
def main(args: Array[String]): Unit = {
try coerce1[Int, String](1).charAt(0) catch {
case e: ClassCastException => println("coerce1 works")
}
try coerce2[Int, String](1).charAt(0) catch {
case e: ClassCastException => println("coerce2 works")
}
try coerce3[Int, String](1).charAt(0) catch {
case e: ClassCastException => println("coerce3 works")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment