简体   繁体   English

处理Scalaz6验证列表

[英]Processing a list of Scalaz6 Validation

Is there an idiomatic way to handle a collection of Validation in Scalaz6? 是否有一种惯用的方法来处理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())

I could think of using a fold when looping on results, but what about the final test? 我可以考虑在循环结果时使用折叠,但最终测试呢?

The usual way to work with a list of validations is to use sequence to turn the list into a Validation[A, List[B]] , which will be be empty (ie, a Failure ) if there were any errors along the way. 使用验证列表的常用方法是使用sequence将列表转换为Validation[A, List[B]] ,如果在此过程中出现任何错误,则Validation[A, List[B]]将为空(即Failure )。

Sequencing a Validation accumulates errors (as opposed to Either , which fails immediately) in the semigroup of the left-hand type. 排序Validation累积了左手类型半群中的错误(与Either相反,后者立即失败)。 This is why you often see ValidationNEL (where the NEL stands for NonEmptyList ) used instead of simply Validation . 这就是为什么你经常看到使用ValidationNEL (其中NEL代表NonEmptyList )而不是简单的Validation So for example if you have this result type: 例如,如果您有此结果类型:

import scalaz._, Scalaz._

type ExceptionsOr[A] = ValidationNEL[Exception, A]

And some results: 还有一些结果:

val results: Seq[ExceptionsOr[Int]] = Seq(
  "13".parseInt.liftFailNel, "42".parseInt.liftFailNel
)

Sequencing will give you the following: 排序将为您提供以下内容:

scala> results.sequence
res0: ExceptionsOr[Seq[Int]] = Success(List(13, 42))

If we had some errors like this, on the other hand: 如果我们有这样的错误,另一方面:

val results: Seq[ExceptionsOr[Int]] = Seq(
  "13".parseInt.liftFailNel, "a".parseInt.liftFailNel, "b".parseInt.liftFailNel
)

We'd end up with a Failure (note that I've reformatted the output to make it legible here): 我们最终会Failure (注意我已经重新格式化输出以使其在这里清晰可见):

scala> results.sequence
res1: ExceptionsOr[Seq[Int]] = Failure(
  NonEmptyList(
    java.lang.NumberFormatException: For input string: "a",
    java.lang.NumberFormatException: For input string: "b"
  )
)

So in your case you'd write something like this: 所以在你的情况下,你会写这样的东西:

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", _)
  )
}

See my answers here and here for more detail about sequence and about Validation more generally. 有关sequenceValidation更多详细信息,请参阅此处此处的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM