处理Scalaz6验证列表

时间:2013-01-09 10:46:37

标签: validation scala scalaz

在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())

我可以考虑在循环结果时使用折叠,但最终测试怎么样?

1 个答案:

答案 0 :(得分:9)

使用验证列表的常用方法是使用sequence将列表转换为Validation[A, List[B]],如果有Failure,它将为空(即Validation)一路上都有任何错误。

排序Either累积左手类型半群中的错误(与ValidationNEL相反,后者立即失败)。这就是为什么您经常看到使用NELNonEmptyList代表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", _)
  )
}

所以在你的情况下,你会写这样的东西:

sequence

有关Validation和{{1}}更多详细信息,请参阅我的答案herehere