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?

Was it helpful?

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)
Licensed under: CC-BY-SA with attribution
scroll top