Почему этот Scala для выражения с использованием кортежей не компилируется? - PullRequest
7 голосов
/ 29 апреля 2011

В Scala 2.8.1 компилируем это:

val t = (40, 2)

println(for ((i, j) <- List(t)) yield i + j)

val e: Either[String, (Int, Int)] = Right(t)
println(e.right.map {
  case (i, j) => i + j
})
println(for ((i, j) <- e.right) yield i + j)

дает это:

test.scala:9: error: constructor cannot be instantiated to expected type;
 found   : (T1, T2)
 required: Either[Nothing,(Int, Int)]
println(for ((i, j) <- e.right) yield i + j)

Согласно Программирование в Scala , выражение for должно быть эквивалентно выражению map / case, но компилируется только последнее. Что я делаю не так и как мне это делать?

Ответы [ 2 ]

11 голосов
/ 29 апреля 2011

На самом деле, это не вполне перевод, который происходит. Вы можете обратиться к этому ответу для более полного руководства, но этот случай явно не упоминается даже там.

Что происходит, так это то, что для понимания с сопоставлением с шаблоном фильтруется несоответствующий регистр. Например,

for((i, j) <- List((1, 2), 3)) yield (i, j)

вернет List((1, 2)): List[(Any, Any)], так как withFilter вызывается первым. Теперь Either, похоже, не имеет withFilter, поэтому он будет использовать filter, и вот фактический перевод этого для понимания:

e.right.filter { case (i, j) => true; case _ => false }.map { case (i, j) => i + j }

Что дает точно такую ​​же ошибку. Проблема в том, что e.right возвращает RightProjection, но filter при RightProjection[A, B] возвращает Option[Either[Nothing, B]].

Причина этого в том, что не существует такого понятия, как «пустой» Either (или RightProjection), поэтому ему необходимо инкапсулировать свой результат в Option.

Сказав все это, действительно удивительно, если взглянуть на уровень понимания. Я думаю, правильнее было бы, если бы filter вернул вместо этого какой-то отфильтрованный прогноз.

2 голосов
/ 29 апреля 2011

Right не возвращает ожидаемый вариант, а RightProjection. Это исправляет это:

println(for ((i, j) <- e.right.toOption) yield i + j)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...