Suppose you define the following class:
case class CaseClass(i: Int, s: String)
with pattern matching, you can achieve what you want with the following:
import scala.reflect.runtime.universe._ typeOf[CaseClass].members.filter(!_.isMethod).map(_.typeSignature).foreach { case t if t == typeOf[Int] => print("i") case s if s == typeOf[String] => print("s") }
Why?
So why is the first attempt not working?
This is because you use type templates in your code. Sample templates check the subjectโs type for consistency โ which is the type signature in this case โ at runtime. Thus, using _: Int , we request a type check at runtime against each type signature of the non-method CaseClass .
But in this case, we need a match of values.
Let's consider in more detail (using Scala REPL):
scala> case class CaseClass(i: Int, s: String) defined class CaseClass scala> typeOf[CaseClass] res1: reflect.runtime.universe.Type = CaseClass scala> typeOf[CaseClass].members res2: reflect.runtime.universe.MemberScope = Scopes(method equals, method toString, ..) scala> typeOf[CaseClass].members.filter(!_.isMethod) res4: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value s, value i) scala> typeOf[CaseClass].members.filter(!_.isMethod).map(_.typeSignature) res5: Iterable[reflect.runtime.universe.Type] = List(String, scala.Int)
So, we want to combine the type reflect.runtime.universe.Type . Note that in the last line, String and scala.Int are just string representations of these types, not their actual type!
Therefore, we need to match them with different values โโof this type, which we can easily get with typeOf[Int] and typeOf[String] .
A bit more about pattern matching in Scala
You can make the code shorter using the following code:
typeOf[CaseClass].members.withFilter(!_.isMethod).map(_.typeSignature).foreach { case typeOf[Int] => print("i")
But this will give you the following compilation error:
not found: type typeOf
Again, this is because here you need to map the variable name starting with an uppercase letter. So, the following works:
val T = typeOf[Int] val S = typeOf[String] typeOf[CaseClass].members.withFilter(!_.isMethod).map(_.typeSignature).foreach { case T => print("i") case S => print("s") }
For more information on pattern matching, see Programming in Scala . You will find a detailed explanation of pattern matching.