2014-10-16 7 views
13

Ich verwende die Scalaz-Validierung und habe einen Code, um Produkte zu validieren.Scalaz-Validierung: Validierungssequenz in eine einzige Validierung umwandeln

def validateProduct(product: Option[Product]): ValidationNel[String, Product] = ??? 

eine Liste der Produkte gegeben, möchte ich die ganze Liste als erfolgreicher Wert oder eine Liste von Validierungsfehlern eine einzelne Validierung erhalten enthält. Es scheint, als ob eine Art von Falte es tun sollte, aber ich bin mir nicht sicher, was die Kombinationsfunktion sein sollte.

def validateProducts(products: Seq[Option[Product]]): ValidationNel[String, Seq[Product]] = { 
    val listOfValidations: Seq[ValidationNel[String, Product]] = products.map(validateProduct _) 
    val validatedList:ValidationNel[Seq[String], Seq[Product]] = ??? // what to do here? 
    ??? 
    } 

Jede Hilfe

Antwort

16

geschätzt Wenn anstelle eines ValidationNel[List[String], List[Product]] wollen Sie ein ValidationNel[String, List[Product]] (dh alle Ausfälle in der gleichen Liste), können Sie nur traverse:

val result: ValidationNel[String, List[Product]] = 
    products.toList.traverseU(validateProduct) 

Hinweis dass ich die Seq in eine List umgewandelt habe, da es keine Klasseninstanzen für rohe Seq gibt, und ich verwende traverseU statt.210 als Scala Typinferenz funktioniert nicht ganz für nicht-triviale Typkonstruktoren wie ValidationNel

+0

Schöne verwenden können! Vielen Dank! – triggerNZ

7

Sie Falte mit applicative

import scalaz.syntax.validation._ 
    import scalaz.syntax.applicative._ 

    case class Product(name: String) 

    val allGood = Seq(
    Product("a").successNel[String], 
    Product("b").successNel[String] 
) 

    val aggregated: ValidationNel[String, Seq[Product]] = 
    allGood.foldLeft(Seq.empty[Product].successNel[String]) { 
    case (acc , v) => (acc |@| v)(_ :+ _) 
    } 

    println(aggregated) 
Verwandte Themen