Scalaz 验证和 ApplicativeBuilder 限制

发布于 2024-11-02 22:37:10 字数 323 浏览 1 评论 0原文

我们在项目中使用 scalaz 验证特征来验证 HTTP 参数。常见情况是采用很少的经过验证的值,并且仅当所有值都有效时才执行必要的操作,否则返回错误列表:

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

这很有效,直到我们必须使用超过 8 个参数,因为 |@|运算符构造 ApplicativeBuilder,它限制为 8 个参数。是否有另一种方法来执行这种一次性验证,最好保持代码可读?

We're using scalaz validation trait in our project to validate HTTP parameters. The common case is taking few validated values and performing neccessary action only if all of them are valid, returning list of errors otherwise:

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

This works nice, until we have to use more than 8 parameters, because |@| operator constructs ApplicativeBuilder, which is limited to 8 arguments. Is there another way to perform such all-at-once validation, preferably keeping the code readable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

从此见与不见 2024-11-09 22:37:10

您想要使用 <*> 方法,以及对 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)

you want to use the <*> method, along with a single call to map (or if you prefer). You can keep using <*> indefinitely.

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)
香橙ぽ 2024-11-09 22:37:10

还有几种方法可以实现此目的:

  1. 将相关函数提升到验证上下文,然后将其应用于值。

    getSomeResponse.lift[({ type L[X] = Validation[Y, X] })#L] apply (
      参数1Val、参数2Val、参数3Val
    )
    
  2. 使用 monad 理解。

    <前><代码>对于{
    x1 <- param1Val
    x2 <- param2Val
    x3 <- param3Val
    } 产生 getSomeResponse(x1, x2, x3)

A couple more ways to do it:

  1. Lift the relevant function to Validation context, and then apply it to the values.

    getSomeResponse.lift[({ type L[X] = Validation[Y, X] })#L] apply (
      param1Val, param2Val, param3Val
    )
    
  2. Use monad comprehension.

    for {
      x1 <- param1Val
      x2 <- param2Val
      x3 <- param3Val
    } yield getSomeResponse(x1, x2, x3)
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文