Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type bound error when creating a tuple in scala

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?

like image 269
darkjh Avatar asked Oct 27 '22 19:10

darkjh


1 Answers

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)
like image 171
Leo C Avatar answered Nov 15 '22 06:11

Leo C