The code below doesn\'t compile if I uncomment the line indicated. The compiler complains: \"stable identifier required\".
val Empty = Stream.empty
val a
You can't "pattern match" on a variable that is not a constant.
Stream.empty is not a "stable" identifier since it represents some method:
/** The empty stream */
override def empty[A]: Stream[A] = Empty
that could potentially return any value at any time.
Compiler isn't aware that its returned value is always Empty, so it detects it as a potential changing variable.
Too deep for it to detect it.
However, when you assign the method's retult to a val (being a stable identifier since immutable), your code is able to process to pattern matching using it.
You might read this, evoking an hypothesis explaining why pattern matching expects a stable identifier.
You can't pattern match on Stream.empty because it is a method (in object Stream) that always returns the empty stream (but the compiler doesn't know that).
Instead of assigning val empty = Stream.empty, you can match on Stream.Empty, which is an Object :
scala> a match {
case Stream.Empty => println("done")
case h #:: tl => println(h)
}