During some experimentation around question Pattern matching a String as Seq[Char], I ran across another weird matching phenomenon. Consider the following code that treats a string as a sequence of characters:
def %%&#(input: String) : String = {
val uha : Seq[Char] = input
uha match {
case Seq() => "Empty"
case Seq(first @ _, 'o', 'o') => "Bar"
case _ => "Oh"
}
}
Calling input on the empty String ""
correctly yields "Empty"
.
However, if I rewrite the first match clause as
case Seq.empty => "Empty"
the matching of ""
fails and matches the default clause instead.
Walking through the Scala library source code (which you shouldn't have to do in an ideal world :-) ) I believe that both Seq()
and Seq.empty
will result in RandomAccessSeq.empty
. Apparently, this does not concur with the phenomenon described above because only Seq()
matches the empty String.
UPDATE: Upon some further experimentation this question can be narrowed down to the following:
val list = List()
>>> list2: List[Nothing] = List()
val emptySeq = Seq.empty
list == emptySeq
>>> res1: Boolean = false
This basically means that an empty Seq
does not automatically equal Seq.empty
.
So when matching against a constant (as opposed to using an extractor as suggested by starblue) this unequality leads to the failing match.
The same is true when interpreting the empty String
as a sequence.