8

Scalaz6 で Validation のコレクションを処理する慣用的な方法はありますか?

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

結果をループするときに折り畳みを使用することを考えることができましたが、最終的なテストはどうですか?

4

1 に答える 1

9

検証のリストを操作する通常の方法はsequence、リストをに変換することです。これは、途中でエラーが発生した場合はValidation[A, List[B]]空(つまり、 )になります。Failure

シーケンスは、左側のタイプの半群でValidationエラーを累積します(すぐに失敗するのとは対照的です)。これが、単にの代わりに(の略で)使用されるEitherことがよくある理由です。したがって、たとえば、この結果タイプがある場合:ValidationNELNELNonEmptyListValidation

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

より一般的なことについての詳細については、ここここで私の答えを参照してください。sequenceValidation

于 2013-01-09T11:55:13.407 に答える