编辑:我错过了你问题标题中提到的Either[Seq[A], Seq[B]]
,但我读到了 "我想要获取第一个错误信息或所有错误信息的连结",这将会给你前者:
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)
使用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))
foldLeft
函数的主体替换为以下内容:for (xs <- acc.right; x <- e.right) yield x :: xs
。 - Ben James:+
)可能会更容易。 - Nicolassequence(Seq(Left("a"), Left("b")))
返回的是Left("b")
而不是第一个失败的Left("a")
。因此,这并不完全符合原始规范。 - sim642