略微简化,我的问题来自一个字符串列表input,我想用函数parse返回解析Either[String,Int].
然后list.map(parse)返回一个Eithers 列表.该程序的下一步是格式化错误消息,总结所有错误或传递解析的整数列表.
让我们来称呼我正在寻找的解决方案partitionEithers.
调用
partitionEithers(List(Left("foo"), Right(1), Left("bar")))
Run Code Online (Sandbox Code Playgroud)
会给
(List("foo", "bar"),List(1))
Run Code Online (Sandbox Code Playgroud)
在标准库中找到这样的东西是最好的.如果没有某种清洁,惯用和有效的解决方案,那将是最好的.还有一些高效的实用功能我可以粘贴到我的项目中就行了.
Scala集合提供了一个partition功能:
val eithers: List[Either[String, Int]] = List(Left("foo"), Right(1), Left("bar"))
eithers.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.map(_.left.get), rightList.map(_.right.get))
}
=> res0: (List[String], List[Int]) = (List(foo, bar),List(1))
Run Code Online (Sandbox Code Playgroud)
UPDATE
如果你想将它包装在一个(甚至有点类型更安全)的泛型函数中:
def partitionEither[Left : ClassTag, Right : ClassTag](in: List[Either[Left, Right]]): (List[Left], List[Right]) =
in.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.collect { case Left(l: Left) => l }, rightList.collect { case Right(r: Right) => r })
}
Run Code Online (Sandbox Code Playgroud)
您可以使用separatefrom MonadPlus(scalaz) 或MonadCombine(cats) :
import scala.util.{Either, Left, Right}
import scalaz.std.list._
import scalaz.std.either._
import scalaz.syntax.monadPlus._
val l: List[Either[String, Int]] = List(Right(1), Left("error"), Right(2))
l.separate
// (List[String], List[Int]) = (List(error),List(1, 2))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
961 次 |
| 最近记录: |