`for` syntax failure for Either


#1

I’m using Scala 2.11.12. The following fails to compile, but if I attempt to desugar it myself, it works.

for {
  x <- Some(3).toRight[String]("").right
  y = 4L
} yield x

Gives

Error:(86, 9) value map is not a member of Product with Serializable with scala.util.Either[String,(Int, Long)]
      x <- Some(3).toRight[String]("").right

However,

Some(3).toRight[String]("").right.map { x =>
  val y = 4L
  x
}

compiles.

Is there another way I should be using for syntax with Either? I tried scalaz.Disjunction and Vector, and those don’t have this problem. I suspect it has something to do with RightProjection and its flatMap requiring an Either, and desugaring does something I don’t know about.


#2

That is deeply weird. Simplifying slightly, I get the same error with:

for {
  x <- Right[Int, String]("hello").right
  y = 4
} yield x

But if I remove the y = 4, it compiles fine, and if I try this with Scala 2.12 it compiles correctly. It smells like a 2.11 bug…


#3

The actual desugaring is

Some(3).toRight[String]("").right.map{ x => 
  val y = 4L
  (x, y)
}.map( x$1 => (x$1: @scala.unchecked) match {
  case ((x @ _), (y @ _)) => x
})

So there’s 2 maps. And when we look at map on RightProjection it returns (something like) an Either. And in 2.11 Either has no map method.


#4

Thanks @Jasper-M. I get that probably someone consciously decided to not add map and flatMap to Either to 2.11, or I would file a bug report and pull request. But adding a call to map for an assignment seems unnecessary. Are there times when it is?


#5

You can’t add it to 2.11 because (1) 2.11 is more or less end-of-life and more importantly (2) that’s a binary incompatible change. That’s the reason that Either only became right biased in 2.12 onwards.

I honestly don’t know. I haven’t thought it through very much either to be honest. But that’s the way it is right now…


#6

In Scala 2.12 Either was redesigned and became right-biased, which means that Right is assumed to be the default case to operate on.
Cats back-ported this behaviour to Scala 2.11 already.
See: Left and Right Bias (from Scala with Cats book)