Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the implicit resolution chain of `<:<`

Tags:

scala

The compiler is able to provide evidence about type parameters, e.g:

def foo[A, B](implicit ev: A <:< B): B

A look at the type definition for <:< in Predef shows

sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
  1. Can anyone explain the implicit resolution chain here? How can $conforms[A]: A <:< A convince the compiler to create an instance of <:<[List[String], Seq[String]] for instance? Or <:<[Dog, Animal]. And what happens if (when) the .asInstanceOf call throws an exception?
  2. Why is the subclassing of => necessary?
like image 568
gogstad Avatar asked Dec 27 '25 22:12

gogstad


1 Answers

You can see it in the scala.Predef object: https://github.com/scala-native/scala-native/blob/master/scalalib/overrides-2.11/scala/Predef.scala#L372

@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable

private[this] lazy val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
@inline implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

@deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
def conforms[A]: A <:< A = $conforms[A]

<:<[-From, +To] contravariant over Form and covariant over To, hence <:<[Seq[String], Seq[String]] is a subtype of <:<[List[String], Seq[String]] (because List[String] is a subtype of Seq[String] and -From is contravariant). So, when you write implicit ev List[String] <:< Seq[String] the compiler use <:<[Seq[String], Seq[String]]

When you write implicit ev T <:< D and there is no A that conforms T <: A <: D, the compiler doesn't compile it, because there is no <:<[A, A] that conforms <:<[A, A] <: <:<[T, D]. So, .asInstanceOf never throws an exception inside $conforms in runtime.

Also, a very good blog post about it: http://blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html

like image 106
Aleksey Isachenkov Avatar answered Dec 30 '25 22:12

Aleksey Isachenkov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!