Transform Either types in Scala
https://softwareengineering.stackexchange.com/questions/291071
Question
I have an Either
type e.g. Either[A, B]
but I want an Either[X, Y]
by using two functions A => X
and B => Y
.
I can do that with fold:
val myEither: Either[A, B] = ...
myEither.fold(
a => Left(createNewX()),
b => Right(createNewY())
)
But that seems redundant to me as I have to repeat the Left
and Right
. I rather want something like:
val myEither: Either[A, B] = ...
myEither.transformToEither(
a => createNewX(),
b => createNewY()
)
which transforms an Either[A, B]
to an Either[X, Y]
by creating a Left
for the result of the first function and a Right
for the second one. What is the most scala-ish way to do it?
Solution
Your first way is probably the best for a one-time deal. If you need to do this a lot, I would add an implicit map
method to Either
that gives you the API you want:
object EitherUtils {
implicit class ImprovedEither[A, B](e: Either[A, B]) {
def map[X, Y](fa: A => X, fb: B => Y): Either[X, Y] = {
e.fold(a => Left(fa(a)), b => Right(fb(b)))
}
}
}
Scalaz adds a bunch of functionality to either, which might be useful if you care enough about scalaz to decipher their documentation.
However, in general you want to think of Either
as a temporary container, occasionally useful for intermediate steps, rather than as something you want to keep around a long time. If you find yourself wanting to operate extensively on an Either
, that should prompt a second look to see if you can refactor it out earlier.
OTHER TIPS
So you want to map left and right of either monad right? Instead of writing fancy utility methods I'd rather stick with vanilla monad transformers since Scala already provides tools to achieve what you want.
val myEither: Either[A, B] = ...
myEither
.map(createNewX)
.left.map(createNewY)