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?

+3


source to share


2 answers


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.

+2


source


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

      

+2


source







All Articles