Scala map only right value and display error for left

I have a sequence of left and right values like:

val l: Seq[Either[Error, Data]] = Seq(Left(Error), Right(Data), ...)

I want to map all Right values and display the error for a Left.
I have tried:

val data: Seq[Data] = l.flatMap {
  case Right(data) => data
  case Left(err)   => println(err) // doesn't work because println is Unit
}

Any way to do this?

>Solution :

It’s generally not a great practice to mix side effects and pure code like this, but something like (assuming a strict Seq):

def rightsAfterEffectingLefts[A, B](eithers: Seq[Either[A, B]])(effect: A => Unit): Seq[B] = {
  eithers.foreach(_.left.foreach(effect))
  eithers.flatMap(_.toOption)
}

val data = rightsAfterEffectingLefts(l)(println _)

It’s possible to optimize to avoid the double iteration, though you’d likely want to approach different Seq implementations differently.

EDIT: after Luis’s suggestion

def rightsAfterEffectingLefts[A, B](eithers: Seq[Either[A, B]])(effect: A => Unit): Seq[B] = {
  val (lefts, rights) = eithers.partition(_.isLeft)
  lefts.foreach(_.left.foreach(effect))
  rights.flatMap(_.toOption)
}

is an alternative definition. It still double iterates and will likely be slower.

Leave a Reply