我正在使用scalaz验证,并有一些代码来验证产品。
def validateProduct(product: Option[Product]): ValidationNel[String, Product] = ???
鉴于产品列表,我想获得一个包含整个列表的验证,作为成功值或验证错误列表。似乎某种折叠应该这样做,但我不确定组合功能应该是什么。
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?
???
}
感谢任何帮助
答案 0 :(得分:16)
如果您需要ValidationNel[List[String], List[Product]]
而不是ValidationNel[String, List[Product]]
(即同一列表中的所有失败),则可以使用traverse
:
val result: ValidationNel[String, List[Product]] =
products.toList.traverseU(validateProduct)
请注意,我已将Seq
转换为List
,因为原始Seq
没有类型类实例,我使用{{1}而不是traverseU
因为Scala的类型推断对于非平凡类型构造函数(例如traverse
答案 1 :(得分:7)
你可以使用fold with 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)