Почему for-comprehension, используемый с экстрактором типа tuple, приводит к предупреждению компиляции о `filter`?

Учитывая следующий фрагмент кода:

import scala.util.Try

def foo(x:Int) : (Int, String) = {
  (x+1, x.toString)
}

def main(args: Array[String]) : Unit = {
  val r1: Try[(Int, String)] = for {
    v <- Try { foo(3) }
  } yield v

  val r2: Try[(Int, String)] = for {
    (i, s)  <- Try { foo(3) } // compile warning refers to this line
  } yield (i, s)
}

<сильный>1. Почему компиляция приведенного выше кода выдает следующее предупреждение?

`withFilter' method does not yet exist on scala.util.Try[(Int, String)], using `filter' method instead
[warn]       (i, s)  <- Try { foo(3) }
[warn]                      ^
[warn] one warning found

<сильный>2. Почему withFilter вообще используется при извлечении в кортеж?

Обновлять

  • Предупреждение появляется с Scala 2.10.5
  • Предупреждение не появляется в Scala 2.11.7.

Независимо от предупреждающего сообщения, мне очень интересно узнать, используется ли withFilter? (см. вопрос 2)


person Martin Senne    schedule 21.10.2015    source источник
comment
Какую версию Scala вы используете?   -  person Peter Neyens    schedule 21.10.2015
comment
@PeterNeyens: Хороший совет! 2.10.5   -  person Martin Senne    schedule 21.10.2015


Ответы (1)


Кажется, Try.withFilter был добавлен только в 2.11 (см. Try 2.10. 6 и Try 2.11.0)

withFilter используется вместо filter в a для понимания, потому что это лениво, вы можете прочитать более полное сравнение в этом вопрос.

Ваша секунда для понимания похожа на:

Try(foo(3)).withFilter {
  case (i, s) => true
  case _      => false
} map(identity)

Поскольку в Scala 2.10.5 Try.withFilter не существует, он возвращается к использованию filter (который создает новый Try).


Редактировать: зачем вам нужен withFilter, в вашем случае не так очевидно, потому что вы на самом деле не фильтруете по шаблону (i, s).

Если вы написали для понимания ниже, становится более ясно, что вы (можете) фильтровать, когда добавляете соответствие шаблону в левой части для понимания.

for {
  (i, "3") <- Try(foo(3))
} yield i

Что аналогично:

Try(foo(3)) withFilter {
  case (i, "3") => true
  case _        => false
} map { case (i, "3") => i }

Как видите, withFilter используется не только при добавлении защиты if, но и при сопоставлении с образцом.

person Peter Neyens    schedule 21.10.2015
comment
Не могли бы вы немного пояснить, почему используется withFilter? Почему это необходимо? - person Martin Senne; 21.10.2015
comment
Заголовок stackoverflow.com/questions/4380831/ - person som-snytt; 22.10.2015