有没有一种惯用的方法来处理Scalaz6中的验证集合?
val results:Seq[Validation[A,B]]
val exceptions = results.collect{case Failure(exception)=>exception}
exceptions.foreach{logger.error("Error when starting up ccxy gottware",_)}
val success = results.collect{case Success(data)=>data}
success.foreach {data => data.push}
if (exceptions.isEmpty)
containers.foreach( _.start())
我可以考虑在对结果进行循环时使用折叠键,但是最终的测试呢?
发布于 2013-01-09 11:55:13
处理验证列表的通常方法是使用sequence
将列表转换为Validation[A, List[B]]
,如果在此过程中出现任何错误,则该列表将为空(即Failure
)。
对Validation
进行排序会在左侧类型的半组中累积错误(与立即失败的Either
相反)。这就是为什么您经常看到使用ValidationNEL
(其中NEL
代表NonEmptyList
)而不是简单地使用Validation
。例如,如果你有这样的结果类型:
import scalaz._, Scalaz._
type ExceptionsOr[A] = ValidationNEL[Exception, A]
以及一些结果:
val results: Seq[ExceptionsOr[Int]] = Seq(
"13".parseInt.liftFailNel, "42".parseInt.liftFailNel
)
排序将为您提供以下内容:
scala> results.sequence
res0: ExceptionsOr[Seq[Int]] = Success(List(13, 42))
如果我们有一些像这样的错误,另一方面:
val results: Seq[ExceptionsOr[Int]] = Seq(
"13".parseInt.liftFailNel, "a".parseInt.liftFailNel, "b".parseInt.liftFailNel
)
我们最终会得到一个Failure
(请注意,我已经重新格式化了输出,使其在这里清晰可读):
scala> results.sequence
res1: ExceptionsOr[Seq[Int]] = Failure(
NonEmptyList(
java.lang.NumberFormatException: For input string: "a",
java.lang.NumberFormatException: For input string: "b"
)
)
因此,在您的示例中,您应该编写如下内容:
val results: Seq[ValidationNEL[A, B]]
results.sequence match {
case Success(xs) => xs.foreach(_.push); containers.foreach(_.start())
case Failure(exceptions) => exceptions.foreach(
logger.error("Error when starting up ccxy gottware", _)
)
}
https://stackoverflow.com/questions/14233511
复制相似问题