I need to reduce an Iterable[Either[Throwable, String]] to an Either[Throwable, Iterable[String]]. I don’t know if this operation is pretty common or not, haven’t found nothing on the Iterable trait. So I have written this function:
def reduce[A, B](xs: Iterable[Either[A, B]]): Either[A, Iterable[B]] =
xs.collectFirst {
case Left(x) => x
} match {
case Some(x) => Left(x)
case None => Right(xs.collect{case Right(y)=> y})
}
Can anyone help me to find a better way if this one it isn’t?
This operation is often called sequencing, and is available in the standard libraries of some functional languages (such as Haskell). In Scala you can either implement your own, or use an external library like Scalaz. Suppose we have the following, for example:
Now we can write (using Scalaz 7):
As desired.
As a side note, this operation just requires that the outside container be traversable and that the inside container be an applicative functor. Scalaz also provides a
ValidationNELclass that’s a lot likeEitherand also fits these requirements, but usingsequenceon a list ofValidationNELs collects multiple errors instead of stopping at the first:Now we get:
You could also use
sequenceon a list ofOptions,Promises, etc.