You can record type information using Manifests. (T, R are invariant here so that everything is simple.)
import scala.reflect._ def matchFunction[T,R](f: Function1[T,R], t : T)(implicit mt : Manifest[T], mr : Manifest[R]) = { val result = if ((mt.erasure, mr.erasure) == (classOf[Any], classOf[Boolean])) "any, boolean " + f(t) else if((mt.erasure, mr.erasure) == (classOf[Int], classOf[Int])) "int, int " + f(t) else "Unknown " + f(t) println(result) } scala> matchFunction((x : Int) => x + 1, 1) int, int 2 scala> matchFunction((x : Any) => true, 1 : Any) any, boolean true scala> matchFunction((x : Boolean) => ! x, false) Unknown
For Scala 2.8, you can use context boundaries by removing two implicit parameters:
import scala.reflect._ def matchFunction[T: Manifest,R : Manifest](f: Function1[T,R], t : T) = { val mt = implicitly[Manifest[T]] val mr = implicitly[Manifest[T]] val result = if ((mt.erasure, mr.erasure) == (classOf[Any], classOf[Boolean])) "any, boolean " + f(t) else if((mt.erasure, mr.erasure) == (classOf[Int], classOf[Int])) "int, int " + f(t) else "Unknown " + f(t) println(result) }
source share