You do either a:
either.left.map(f)
or a:
either.right.map(f)
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)
either: Either[Boolean, Int] = Right(5)
scala> val e2 = either.right.map(_ > 0)
either: Either[Boolean, Boolean] = Right(true)
scala> e2.left.map(!_)
either: Either[Boolean, Boolean] = Right(true)
EDIT:
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.