scala - 如何将 Seq[Either[A,B]] 减少为 Either[A,Seq[B]]?

标签 scala functional-programming scalaz scala-cats

给定一个序列 Seq[Either[String,A]],其中 Left 是错误消息。我想获得一个 Either[String,Seq[A]] ,其中我得到一个 Right (这将是一个 Seq[A]) ,如果序列的所有元素都是Right。如果至少有一个 Left (错误消息),我想获取第一条错误消息或所有错误消息的串联。

当然,您可以发布 cats 或 scalaz 代码,但我也对不使用它的代码感兴趣。

编辑

我更改了标题,该标题最初要求使用 Either[Seq[A],Seq[B]] 来反射(reflect)消息正文。

最佳答案

编辑:我错过了您问题的标题要求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))

关于scala - 如何将 Seq[Either[A,B]] 减少为 Either[A,Seq[B]]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7230999/

相关文章:

scala - 如何从Gradle执行Scala脚本?

java - (另一个)Neo4j 插件未显示在扩展中

parsing - Monad 解析器 - 无法将预期类型 ‘[(b, String)]’ 与实际类型 ‘Parser b’ 匹配

c++ - 将 n 个 vector 组合成一个 n 元组 vector

scala - 组合 2 个列表的元素

scala - 如何将 Spark 中的分类变量转换为一组编码为 {0,1} 的列?

scala - "val a:A = new B ",有什么意义?

scala:将错误添加到错误列表的惯用和功能方式

scala - 如何结合 Reader 和 State monad

scala - 在元组中使用 FirstOption monoid 实例