I have an extential type of tuple, and I want to pass it to a generic function (I use ClassTag in this example but it is a custom type class with invariant type parameter):
type TC = (ClassTag[T], Option[T]) forSome {type T}
def foo[T](ct: ClassTag[T], o: Option[T]) = {}
val tc: TC = (classTag[String], Option[String](null))
foo(tc._1, tc._2)
This gives me error:
error: type mismatch; found : scala.reflect.ClassTag[T] required: scala.reflect.ClassTag[Any] Note: T <: Any, but trait ClassTag is invariant in type T. You may wish to investigate a wildcard type such as
_ <: Any
. (SLS 3.2.10) foo(tc._1, tc._2)
I wanna ensure the type of two parameters ct
and o
uses the same parameter type T and I thought extential type should ensure this, but it does not seem to work.
However if I don't use tuple and only use ClassTag, it works fine:
type TC = ClassTag[T] forSome {type T}
def foo[T](ct: ClassTag[T]) = {}
val tc: TC = classTag[String]
foo(tc)
So the previous error of ClassTag invariance does not make sense.
Why does it not work when I use a tuple? How can I make it work?