Even after learning about static overloading in Scala (What is Scala's static overloading rule?), I still am unable to use it for the <:<
class.
This class is used to check for subclassing, and is defined in Predef
:
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
However when I write A <:< B
I am not sure if I am using an instance of <:<[A,A]
or<:<[B,B]
, because following the static overloading rule neither is more specific then the other.
We first try this just to be sure it really works, replacing <:<
with my mycic
:
class superC
class subC extends superC
abstract class mycic[-From,+To] extends ((From) => To) with Serializable
object Main extends App {
implicit def FandT[A]: mycic[A,A] = new (mycic[A,A]) { def apply(x: A) ={x}}
val e = implicitly[subC mycic superC]
val a = new subC
e.apply(a)
}
This runs nicely. But when we try to define which one it is using:
class superC
class subC extends superC
abstract class mycic[-From,+To] extends ((From) => To) with Serializable
object Main extends App {
implicit val FF : mycic[subC,subC] = new(mycic[subC,subC]){def apply(x:subC) ={println("FF");x}}
implicit val TT : mycic[superC,superC] = new(mycic[superC,superC]){def apply(x:superC) ={println("TT");x}}
val e = implicitly[subC mycic superC]
val a = new subC
e.apply(a)
}
we get the following compilation error:
Main.scala:10: error: ambiguous implicit values:
both value TT in object Main of type => mycic[superC,superC]
and value FF in object Main of type => mycic[subC,subC]
match expected type mycic[subC,superC]
val e = implicitly[subC mycic superC]
^
Which implicit instance of mycic
is it using in the code that runs? Why does it behave differently in the second example?