When you compiled this code:
def containsType[T] = l.exists(_.isInstanceOf[T])
You should have seen this warning:
warning: abstract type T is unchecked since it is eliminated by erasure
This warning isn’t some stylistic nitpick it’s safe to ignore; it’s telling you that this code is wrong and will not operate as intended. Arguably the compiler ought to issue an error here, not merely a warning.
I hesitate to offer the following, because you’re still learning Scala and what I’m about to say is fairly advanced Scala, not beginning Scala. Part of learning a new language is learning which coding patterns are considered usual and normal and which coding patterns are considered something you reach for only in unusual situations or as a last resort.
That said, it is possible to define something like what you wanted by requiring a ClassTag
:
def containsClass[T : reflect.ClassTag] =
l.exists{case x: T => true; case _ => false}
Note that I changed from isInstanceOf
to a pattern match because pattern matching has special support for implicit ClassTag
s but isInstanceOf
does not. (Normal Scala code rarely uses isInstanceOf
at all.)
Also note that I changed the method name because we are doing a compile-time type test here. We’re doing a runtime check on what class something is, which is the most we can do, because types are a compile-time concept; full type information doesn’t exist at runtime.
So now I can:
scala> containsClass[Boolean]
val res0: Boolean = false
scala> containsClass[String]
val res1: Boolean = true
But note that this won’t warn us if we provide a more specific type than can actually be checked:
scala> containsClass[List[Int]]
val res5: Boolean = true
scala> containsClass[List[String]]
val res6: Boolean = true
where the latter result isn’t as intended and isn’t even giving us a warning.
Anyway, I’m not going to launch into a full explanation of all this at the moment. And I repeat that this is runtime reflection, not normal Scala, and we don’t normally program this way in Scala – certainly not when we’re just learning the language.
Statically typed languages and dynamic languages are really deeply, fundamentally different from each other and this deep difference results in different coding patterns and different ways of thinking about code.