Reputation: 5933
In Scala, I'm trying:
import scala.reflect.runtime.{universe => ru}
def foo[T <: Any]: ru.WeakTypeTag[T] = ru.weakTypeTag[String]
But this yields me:
<console>:34: error: type mismatch;
found : reflect.runtime.universe.WeakTypeTag[String]
required: reflect.runtime.universe.WeakTypeTag[T]
def foo[T <: Any]: ru.WeakTypeTag[T] = ru.weakTypeTag[String]
What's up here? I'm relatively sure String
should satisfy T
's type constraint of deriving from Any
...
I guess String
failed to bind to the T
type parameter. In my use case other types may be returned as well though, and I'm not sure how I could get that answer to the compiler up-front before executing the function, if that's what it's expecting.
Upvotes: 0
Views: 751
Reputation: 6395
As an alternative you can use wildcard, anyway your type is extended from Any.
def foo[T <: Any]: ru.WeakTypeTag[_] = ru.weakTypeTag[String]
In general the problem is with definition of WeakTypeTag[T] class. It is defined invariantly. So you can not use it in covariant case.
Let's go with an examples.
def bom[T >: String]: List[T] = List[String]() // works fine
def foo[T >: String]: WeakTypeTag[T] = ru.weakTypeTag[String] // compilation fails
I'm defining T as any subtype of String and it works good for Lists
but fails for WeakTypeTag
that is invariant.
You can define sub type of WeakTypeTag
and make it covariant so it will perfectly works.
trait WeakTypeTag1[+X] extends ru.WeakTypeTag {
}
def weakTypeTag1[T](implicit attag: WeakTypeTag1[T]) = attag
def foo[T >: String]: WeakTypeTag1[T] = weakTypeTag1[String] // no it's good
Upvotes: 1
Reputation: 24832
Your method foo
claims that, for any T <: Any
, it returns a WeakTypeTag[T]
. That is, if T
is (for instance) Int
, it should return a WeakTypeTag[Int]
. However, your method always returns a WeakTypeTag[String]
, hence the type mistmatch.
Upvotes: 6