As I note in a comment above, the problem is that the desugared version of your second for
-comprehension involves a filtering operation in 2.10.2 (and 2.10.1, but not 2.10.0), and it's not possible to filter EitherT
(or plain old \/
) without a monoid instance for the type on the left side.
It's pretty easy to see why the monoid is necessary in the following example:
val x: String \/ Int = 1.right
val y: String \/ Int = x.filter(_ < 0)
What is y
? It's clear that it has to be some kind of "empty" String \/ Int
, and since \/
is right-biased, we know that it can't be a value on that side. So we need a zero for the left side, and the monoid instance for String
provides this—it's just the empty string:
assert(y == "".left)
According to this answer to my related question about tuple patterns in for
-comprehensions, the behavior you're seeing in 2.10.2 is correct and intended—the apparently completely unnecessary call to withFilter
is here to stay.
You can use the workaround in Petr Pudlák's answer, but it's also worth noting that the following sugar-free version is also pretty clear and concise:
val notAnotherComprehension = comprehension.flatMap {
case (x, y) => doSomething.map((x, y, _))
}
This is more or less what I would naïvely expect the for
-comprehension to desugar to, anyway (and I'm not the only one).