Scalaz验证和ApplicativeBuilder限制

时间:2011-04-21 07:30:14

标签: validation scala scalaz

我们在项目中使用scalaz验证特性来验证HTTP参数。常见的情况是,只有在所有值都有效的情况下,只需要很少的验证值并执行必要的操作,否则返回错误列表:

(pavam1Val.liftFailNel |@|
 param2Val.liftFailNel |@|
 param3Val.liftFailNel) {
    getSomeResponse(_, _, _)
}

这很好用,直到我们必须使用8个以上的参数,因为| @ | operator构造ApplicativeBuilder,限制为8个参数。是否有其他方法可以执行此类一次性验证,最好是保持代码可读?

2 个答案:

答案 0 :(得分:11)

您想使用<*>方法,只需拨打map(或,如果您愿意)。您可以无限期地继续使用<*>

scala> val param1Val = success[String, Int](7)                              
param1Val: scalaz.Validation[String,Int] = Success(7)

scala> val param2Val = failure[String, Int]("abc")                          
param2Val: scalaz.Validation[String,Int] = Failure(abc)

scala> val param3Val = success[String, Int](9)                              
param3Val: scalaz.Validation[String,Int] = Success(9)

scala> val r = param1Val <*> (param2Val <*> (param3Val map getSomeResponse))
r: scalaz.Validation[String,Int] = Failure(abc)

答案 1 :(得分:2)

还有几种方法可以做到:

  1. 将相关功能提升至Validation上下文,然后将其应用于值。

    getSomeResponse.lift[({ type L[X] = Validation[Y, X] })#L] apply (
      param1Val, param2Val, param3Val
    )
    
  2. 使用monad理解。

    for {
      x1 <- param1Val
      x2 <- param2Val
      x3 <- param3Val
    } yield getSomeResponse(x1, x2, x3)