Take the 2-minute tour ×

I'm probably missing something that's right in the documentation, but I can't really make much sense of it - I've been teaching myself Scala mostly by trial and error.

Given a function f: A => C, what is the idiomatic way to perform the following conversions?

Either[A, B] -> Either[C, B]

Either[B, A] -> Either[B, C]

(If I have two such functions and want to convert both sides, can I do it all at once or should I apply the idiom twice sequentially?)

Option[A] -> Option[C]

(I have a feeling that this is supposed to use for (...) yield somehow; I'm probably just blanking on it, and will feel silly when I see an answer)

And what exactly is a "projection" of an Either, anyway?

share|improve this question
From a comment below you seem to be confusing Either with a Pair, a Tuple2. That is not the case: an Either can only contain one value. In a sense, it is similar to union in C, except that you know which member is actually stored. –  Daniel C. Sobral Sep 21 '11 at 21:37
I'm aware of that, but I still get confused one projections are thrown into the mix. I didn't really express that one clearly. –  Karl Knechtel Sep 21 '11 at 21:42
add comment

3 Answers

up vote 15 down vote accepted

You do either a:


or a:


You can also use a for-comprehension: for (x <- either.left) yield f(x)

Here's a more concrete example of doing a map on an Either[Boolean, Int]:

scala> val either: Either[Boolean, Int] = Right(5)

scala> val e2 = either.right.map(_ > 0)
either: Either[Boolean, Boolean] = Right(true)

scala> e2.left.map(!_)


How does it work? Say you have an Either[A, B]. Calling left or right creates a LeftProjection or a RightProjection object that is a wrapper that holds the Either[A, B] object.

For the left wrapper, a subsequent map with a function f: A => C is applied to transform the Either[A, B] to Either[C, B]. It does so by using pattern matching under the hood to check if Either is actually a Left. If it is, it creates a new Left[C, B]. If not, it just changes creates a new Right[C, B] with the same underlying value.

And vice versa for the right wrapper. Effectively, saying either.right.map(f) means - if the either (Either[A, B]) object holds a Right value, map it. Otherwise, leave it as is, but change the type B of the either object as if you've mapped it.

So technically, these projections are mere wrappers. Semantically, they are a way of saying that you are doing something that assumes that the value stored in the Either object is either Left or Right. If this assumption is wrong, the mapping does nothing, but the type parameters are changed accordingly.

share|improve this answer
Break down how this works for me, please? Something to do with the projections? Evidently .left and .right here are not like in other languages with library "pair" types, where they would just access the members of type [A] and [B] respectively. –  Karl Knechtel Sep 21 '11 at 21:22
You may have a look at that question : stackoverflow.com/q/7131076/754787 –  Didier Dupont Sep 21 '11 at 21:32
I've edited the answer to explain a little bit of what happens under the hood. But, either is not a pair, or a tuple type, also called an intersection type - A x B. It holds either a member of type [A] or [B] - A V B. This means that you cannot safely access either member, like you could in a tuple, because only one member is present. –  axel22 Sep 21 '11 at 21:36
... Beautiful. And how about with an Option? Just for (x <- option) yield f(x), since the Option is already iterable? –  Karl Knechtel Sep 21 '11 at 21:45
@Karl Option is not an Iterable, but it implements the method map, so that is enough. –  Daniel C. Sobral Sep 21 '11 at 21:49
show 2 more comments

Given f: A=>B and xOpt: Option[A], xOpt map f produces the Option[B] you need.

Given f: A=>B and xOrY: Either[A, C], xOrY.left.map(f) produces the Either you are looking for, mapping just the first component; similarly you can deal with RightProjection of Either.

If you have two functions, you can define mapping for both components, xOrY.fold(f, g).

share|improve this answer
add comment
val e1:Either[String, Long] = Right(1)
val e2:Either[Int,Boolean] = e1.left.map(_.size).right.map( _ >1 )
// e2: Either[Int,Boolean] = Right(false)
share|improve this answer
add comment

Your Answer


