Новое десагерирующее поведение в Scala 2.10.1
Предположим, у меня есть этот монадический класс:
case class Foo[A](xs: List[A]) {
def map[B](f: A => B) = Foo(xs map f)
def flatMap[B](f: A => Foo[B]) = Foo(xs flatMap f.andThen(_.xs))
def withFilter(p: A => Boolean) = {
println("Filtering!")
Foo(xs filter p)
}
}
Следующее из сессии REPL 2.10.0:
scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a
res0: Foo[Int] = Foo(List(1))
И вот то же самое в 2.10.1:
scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a
Filtering!
res0: Foo[Int] = Foo(List(1))
Это совершенно неожиданно (для меня) и приводит к особенно запутанным ошибкам в случаях, когда фильтрация требует дополнительных ограничений (таких как Scalaz \/
или жеEitherT
).
Я не смог найти никакого обсуждения этого изменения в примечаниях к выпуску 2.10.1. Может ли кто-нибудь указать, где и почему было введено это новое поведение отладки?
1 ответ
Эта история более сложна, и на самом деле это была регрессия 2.10.0, которая была там включена.
Нет- withFilter
"поведение было введено в c82ecab, и из-за таких вещей, как SI-6968, это было частично отменено # 1893. Последовали дальнейшие адаптации ( SI-6646, SI-7183)
Выносимое предложение, которое вы ищете:
Синтаксический анализатор не может предположить, что шаблон (a, b) будет совпадать, так как результаты.isInstanceOf[Tuple2] не могут быть статически известны до окончания типа.