Почему я не могу сопоставить шаблон по Stream.empty в Scala?
Код ниже не компилируется, если я раскомментировал указанную строку. Компилятор жалуется: "требуется стабильный идентификатор".
val Empty = Stream.empty
val a = Stream.range(0, 5)
a match {
// case Stream.empty => println("nope") <-- does not work
case Empty => println("compiles") <-- works
case _ => println("ok")
}
Если я сначала присваиваю Stream.empty
значение Empty
, это работает, но странно, что вы не можете сопоставить образ с таким фундаментальным значением без такого взлома.
Я что-то пропустил?
Ответы
Ответ 1
Вы не можете сопоставить образ на Stream.empty
, потому что это метод (в объекте Stream
), который всегда возвращает пустой поток (но компилятор этого не знает).
Вместо назначения val empty = Stream.empty
вы можете сопоставлять Stream.empty
, который является Object
:
scala> a match {
case Stream.Empty => println("done")
case h #:: tl => println(h)
}
Ответ 2
Вы не можете "сопоставить шаблон" с переменной , которая не является константой.
Stream.empty
не является "стабильным" идентификатором, поскольку он представляет некоторый метод:
/** The empty stream */
override def empty[A]: Stream[A] = Empty
который потенциально может вернуть любое значение в любое время.
Компилятор не знает, что его возвращаемое значение всегда Empty
, поэтому оно обнаруживает его как потенциальную переменную .
Слишком глубоко, чтобы это обнаружить.
Однако, когда вы назначаете метод retult на val
(являющийся стабильным идентификатором с неизменяемым), ваш код может обрабатывать его с помощью шаблона.
Вы можете прочитать this, вызывая гипотезу, объясняющую, почему соответствие шаблонов ожидает стабильного идентификатора.