In Scala it is possible formulate patterns based on the invididual characters of a string by treating it as a Seq[Char].
An example of this feature is mentioned in
I'm going to echo everything that andri said. For interoperability, Scala strings are java.lang.String
s. In Predef
, there's an implicit conversion from String
to RichString
, which implements Seq[Char]
.
A perhaps nicer way of coding the pattern match, without needing an intermediate val z
to hold the Seq[Char]
:
def containsScala(x: String): Boolean = {
(x: Seq[Char]) match {
...
}
}
There is some real abuse of terminology going on in the question and the comments. There is no cast in this code, and especially "So basically, this is a major concession to Java interoperability, sacrificing some type soundness" has no basis in reality.
A scala cast looks like this: x.asInstanceOf[Y]
.
What you see above is an assignment: val z: Seq[Char] = x
This assignment is legal because there is an implicit conversion from String
to Seq[Char]
. I emphasize again, this is not a cast. A cast is an arbitrary assertion which can fail at runtime. There is no way for the implicit conversion to fail.
The problem with depending on implicit conversions between types, and the answer to the original question, is that implicit conversions only take place if the original value doesn't type check. Since it's perfectly legal to match on a String, no conversion takes place, the match just fails.
Not 100% sure if this is correct, but my intuition says that without this explicit cast you would pattern match against java.lang.String
, which is not what you want.
The explicit cast forces the Scala compiler to use Predef.stringWrapper implicit conversion; thus, as RichString extends Seq[Char], you are able to do a pattern match as if the string were a sequence of characters.