Fil*_*uca 8 functional-programming iterable scala either
我需要将Iterable [[Throwable,String]]减少为[Throwable,Iterable [String]].我不知道这个操作是否相当普遍,在Iterable特征上没有发现任何内容.所以我写了这个函数:
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})
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我找到一个更好的方法,如果这不是吗?
Tra*_*own 11
此操作通常称为排序,可在某些函数语言(如Haskell)的标准库中使用.在Scala中,您可以实现自己的,也可以使用Scalaz之类的外部库.假设我们有以下内容,例如:
val xs: List[Either[String, Int]] = List(Right(1), Right(2))
val ys: List[Either[String, Int]] = List(Right(1), Left("1st!"), Left("2nd!"))
Run Code Online (Sandbox Code Playgroud)
现在我们可以写(使用Scalaz 7):
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> xs.sequenceU
res0: Either[String,List[Int]] = Right(List(1, 2))
scala> ys.sequenceU
res1: Either[String,List[Int]] = Left(1st!)
Run Code Online (Sandbox Code Playgroud)
如预期的.
作为旁注,该操作仅需要外部容器可穿过并且内部容器是应用仿函数.Scalaz还提供了ValidationNEL一个非常类似的类Either并且也符合这些要求,但是sequence在ValidationNELs 列表上使用会收集多个错误而不是在第一个停止:
val zs: List[ValidationNEL[String, Int]] =
List(1.successNel, "1st".failNel, "2nd".failNel)
Run Code Online (Sandbox Code Playgroud)
现在我们得到:
scala> print(zs.sequenceU)
Failure(NonEmptyList(1st, 2nd))
Run Code Online (Sandbox Code Playgroud)
您也可以sequence在Options,Promises等列表中使用.
| 归档时间: |
|
| 查看次数: |
1096 次 |
| 最近记录: |