Say I have a type
trait Mode[T]
trait MyType[T, M <: Mode[T]]
This compiles
val t: MyType[_, _] = ???
t
But not this one
val t: MyType[_, _] = ???
"some_string" -> t
Error says something like type arguments [_$0,_$1] do not conform to trait MyType's type parameter bounds
So my question is that why this does not compile on tuple creation?
Actually both t
and "some string" -> t
will break at runtime with the same issue:
import scala.language.existentials
import scala.reflect.runtime.universe._
type SubMode[T] = M forSome { type M <: Mode[T] }
val t: MyType[_, _] = new MyType[String, SubMode[String]] {}
// t: MyType[_, _] = $anon$1@596afb2f
"some string" -> t
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
reify(t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
reify("some string" -> t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
In fact, the issue at compile-time is not specific to Tuples. For example:
List(t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
My guess is that while the definition of t
alone does not trigger a compilation error, an additional "touch" on t
might. It'll all work fine if you let the compiler infer the proper type:
val t2 = new MyType[String, SubMode[String]] {}
t2: MyType[String,SubMode[String]] = $anon$1@19d53ab4
"some string" -> t2
// res1: (String, MyType[String,SubMode[String]]) = (some string,$anon$1@19d53ab4)
List(t2)
// res2: List[MyType[String,SubMode[String]]] = List($anon$1@19d53ab4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With