Why doesn't TypeTag work for return types?
Seems to TypeTags
only work for type parameters that are used in the parameters of the called method, not the return type:
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime.universe._
object Test {
def withParam[T: TypeTag](v: T): T = {
println(typeOf[T])
0.asInstanceOf[T]
}
def justReturn[T: TypeTag](): T = {
println(typeOf[T])
0.asInstanceOf[T]
}
}
// Exiting paste mode, now interpreting.
import scala.reflect.runtime.universe._
defined module Test
scala> val i: Int = Test.withParam(17)
Int
i: Int = 0
scala> val j: Int = Test.justReturn()
Nothing
j: Int = 0
This is consistent with the behavior of the Manifest in 2.9, but is there some reason it can't be done, and is there another way to achieve this effect?
source to share
The type system begins with the most restrictive type (i.e. Nothing
, of which there can be no instances, if it were a divine value capable of sustaining anything and doing something). The type then expands as needed, but since the return is in a contravariant position, there will never be a reason to expand. If you can truly return Nothing
, you must be set in all situations.
Then you destroy the type system by telling it what 0
is an instance Nothing
. Of course, this is completely wrong, but the compiler obediently trusts you, and you save the situation by assigning it Int
, which it really was. (It String
'll also happily try to assign it , and then you'll get a runtime exception, because it's pointless at that point.)
In theory, this can be done differently, but this is a fairly simple part of the type inference algorithm.
source to share
To expand on Rex Kerr's comment, justReturn
there is nothing logical in the case T
. If you give the parameter a (suitable) type, you get this:
scala> val j: Int = Test.justReturn[Int]()
Int
j: Int = 0
If you change justReturn
to this:
def justReturn[T: TypeTag]() {
println(typeOf[T])
}
... then you can do this:
scala> justReturn[String]()
String
scala> justReturn[java.io.File]()
java.io.File
source to share