How to reduce Seq[Either[A,B]] to Either[A,Seq[B]]?

前端 未结 8 1383
孤城傲影
孤城傲影 2020-12-05 01:31

Given a sequence of eithers Seq[Either[String,A]] with Left being an error message. I want to obtain an Either[String,Seq[A]] where I

8条回答
  •  天命终不由人
    2020-12-05 02:17

    Edit: I missed that the title of your question asked for Either[Seq[A],Seq[B]], but I did read "I'd like to obtain the first error message or a concatenation of all error messages", and this would give you the former:

    def sequence[A, B](s: Seq[Either[A, B]]): Either[A, Seq[B]] =
      s.foldRight(Right(Nil): Either[A, List[B]]) {
        (e, acc) => for (xs <- acc.right; x <- e.right) yield x :: xs
      }
    
    scala> sequence(List(Right(1), Right(2), Right(3)))
    res2: Either[Nothing,Seq[Int]] = Right(List(1, 2, 3))
    
    scala> sequence(List(Right(1), Left("error"), Right(3)))
    res3: Either[java.lang.String,Seq[Int]] = Left(error)
    

    Using Scalaz:

    val xs: List[Either[String, Int]] = List(Right(1), Right(2), Right(3))
    
    scala> xs.sequenceU
    res0:  scala.util.Either[String,List[Int]] = Right(List(1, 2, 3))
    

提交回复
热议问题