2013-01-09 5 views
8

Czy istnieje idiomatyczny sposób obsługi zbioru sprawdzania poprawności w programie Scalaz6?Przetwarzanie listy sprawdzania 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()) 

Mógłbym pomyśleć o zastosowaniu zagięcia podczas zapętlania wyników, ale co z ostatecznym testem?

Odpowiedz

9

Zwykły sposób pracować z listą walidacji jest użycie sequence włączyć listę do Validation[A, List[B]], które będą być pusty (tj Failure) jeśli były jakieś błędy po drodze.

Sekwencjonowanie Validation powoduje kumulację błędów (w przeciwieństwie do Either, które nie powiedzie się natychmiast) w półgrupie typu lewej ręki. Dlatego często widzisz ValidationNEL (gdzie NEL oznacza NonEmptyList) używane zamiast po prostu Validation. Tak na przykład, jeśli masz tego typu wynik:

import scalaz._, Scalaz._ 

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

a niektóre wyniki:

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

Sekwencjonowanie daje następujące:

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

Gdybyśmy mieli jakieś błędy jak ten, z drugiej strony:

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

Chcemy skończyć z Failure (zauważ, że mam przeformatowanym wyjście aby czytelne tutaj):

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

Więc w przypadku, gdy chcesz napisać coś takiego:

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

Zobacz moje odpowiedzi here i here po więcej szczegółów na temat sequence i około Validation bardziej ogólnie.

+0

Co powiecie na bezpłatną sprawę? Chcę odnieść sukces, jeśli udało się co najmniej walidację? – Edmondo1984

+0

Wygląda na to, że możesz pracować przeciwko ziarnu "Walidacji". W 7 możesz zmniejszyć listę za pomocą '|||', ale w 6 będziesz potrzebował czegoś takiego jak suma używając półgrupy dla prawej projekcji 'Albo" (albo możesz napisać własną '|||'). –

+0

Czy możesz wskazać mi jakieś zasoby, które wyjaśniają, czym jest półgrupa? – Edmondo1984