我们在项目中使用scalaz验证特性来验证HTTP参数。常见的情况是,只有在所有值都有效的情况下,只需要很少的验证值并执行必要的操作,否则返回错误列表:
(pavam1Val.liftFailNel |@|
param2Val.liftFailNel |@|
param3Val.liftFailNel) {
getSomeResponse(_, _, _)
}
这很好用,直到我们必须使用8个以上的参数,因为| @ | operator构造ApplicativeBuilder,限制为8个参数。是否有其他方法可以执行此类一次性验证,最好是保持代码可读?
答案 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)
还有几种方法可以做到:
将相关功能提升至Validation
上下文,然后将其应用于值。
getSomeResponse.lift[({ type L[X] = Validation[Y, X] })#L] apply (
param1Val, param2Val, param3Val
)
使用monad理解。
for {
x1 <- param1Val
x2 <- param2Val
x3 <- param3Val
} yield getSomeResponse(x1, x2, x3)