2014-10-16 15 views
13

Tôi đang sử dụng xác thực scalaz và có một số mã để xác thực sản phẩm.Xác thực Scalaz: chuyển đổi chuỗi xác thực thành một xác thực đơn

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

Cung cấp danh sách sản phẩm, tôi muốn nhận được một xác thực duy nhất chứa toàn bộ danh sách dưới dạng giá trị thành công hoặc danh sách lỗi xác thực. Nó có vẻ như một số loại gấp nên làm điều đó, nhưng tôi không chắc chắn những gì các chức năng kết hợp nên được.

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? 
    ??? 
    } 

Any help is appreciated

Trả lời

16

Nếu thay vì một ValidationNel[List[String], List[Product]] bạn muốn có một ValidationNel[String, List[Product]] (tức là, tất cả những thất bại trong cùng một danh sách), bạn chỉ có thể sử dụng traverse:

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

Note rằng tôi đã chuyển đổi Seq thành List vì không có trường hợp loại nào cho số Seq và tôi đang sử dụng traverseU thay vì.210 as type suy luận Scala của không khá làm việc cho nhà xây dựng loại không tầm thường như ValidationNel

+0

đẹp! Cảm ơn bạn! – triggerNZ

7

Bạn có thể sử dụng lần với 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) 
Các vấn đề liên quan