For completeness only, when you are in the Scala REPL, you can access the type as:
scala> val fn = (a: String, b: Double) => 123 fn: (String, Double) => Int = <function2> scala> :type fn (String, Double) => Int
At runtime, Scala compiler will not have complete type information. Thus, it forms a code fragment fn (also searches for its own symbol tables). https://github.com/scala/scala/blob/v2.10.5/src/compiler/scala/tools/nsc/interpreter/ILoop.scala#L449
Then it passes it to the compiler, which then binds the type information to the implicit evidence type.
(explained here I want to get the type of a variable at runtime )
scala> import scala.reflect.runtime.universe.{TypeTag, typeTag} import scala.reflect.runtime.universe.{TypeTag, typeTag} scala> def getTypeTag[T: TypeTag](obj: T) = typeTag[T] getTypeTag: [T](obj: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
Now we have evidence that will give us accurate type information:
scala> getTypeTag(fn) res0: reflect.runtime.universe.TypeTag[(String, Double) => Int] = TypeTag[(String, Double) => Int] scala> val targs = res0.tpe.typeArgs targs: List[reflect.runtime.universe.Type] = List(String, Double, Int)
Now we can easily access these types:
scala> val (in, out) = (ta.init, ta.last) in: List[reflect.runtime.universe.Type] = List(String, Double) out: reflect.runtime.universe.Type = Int scala> println(s"INPUTS: $in") INPUTS: List(String, Double) scala> println(s"OUTPUT: $out") OUTPUT: Int