如何在 Scala 中实现简单的验证 [英] How to implement simple validation in Scala

查看:52
本文介绍了如何在 Scala 中实现简单的验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我需要验证请求参数.验证结果为 SuccessFailureNonEmptyList[String].我可能可以使用 ValidationNel[String, Unit] 但这似乎有点矫枉过正.我想我需要一个更简单的抽象(见下文).

Suppose I need to validate request parameters. The validation result is either Success or Failure with NonEmptyList[String]. I can probably use ValidationNel[String, Unit] but it seems a bit overkill. I guess I need a simpler abstraction (see below).

trait ValidationResult
object Success extends ValidationResult
class Failure(errors: NonEmptyList[String]) extends ValidationResult

和一个二元运算andAlso组合两个结果:

and a binary operation andAlso to combine two results:

trait ValidationResult {
  def andAlso(other: ValidationResult): ValidationResult = 
    (this, other) match {
      case (Success, Success) => Success
      case (Success, failure @ Failure(_)) => failure
      case (failure @ Failure(_), Success) => failure
      case (Failure(errors1), Failure(errors2)) => Failure(errors1 + errors2) 
    } 
}

现在,如果我使用函数 checkAcheckBcheckC 验证三个参数,我可以轻松地将它们组合如下:

Now if I validate three parameters with functions checkA, checkB, and checkC I can easily compose them as follows:

def checkA(a: A): ValidationResult = ...
def checkB(b: B): ValidationResult = ...
def checkC(c: C): ValidationResult = ...
def checkABC(a: A, b: B, c: C) = checkA(a) andAlso checkB(b) andAlso checkC(c)

有意义吗?
这个抽象有名字吗?也许是 Monoid ?
它是在 scalaz 或任何其他 Scala 库中实现的吗?

Does it make sense ?
Does this abstraction have a name ? Maybe a Monoid ?
Is it implemented in scalaz or any other scala library ?

推荐答案

它确实是一个 Monoid,你可以更精确:它是一个 List[String]代码>(直至同构).ValidationResult 确实与 List[String] 同构,Success 表示 NilandAlso 是连接 :::/++.

It is indeed a Monoid, and you can be much more precise : it is a List[String] (up to an isomporphism). ValidationResult is indeed isomorphic to a List[String], with Success for Nil, and andAlso is concatenation ::: / ++.

这是有道理的,ValidationResult 是一个错误列表,如果没有,则意味着成功.

This makes sense, a ValidationResult is a list of errors, and when there are none, that means success.

然而,正如您在开头所指出的,这一切都相当于使用 ValidationNel[String, Unit],其中 Unit,没有感兴趣的数据"是有趣的部分.如果意味着您将单独处理实际数据.在这里你可能会赢一点,那一点是避免了 Applicative 的语法,在你的代码中加入 |@| 之类的;此外,Monads and Co 的价格不常被提及,使调试器更容易使用.但是有一个缺点,随着您的代码随着可能发生错误的地方增加而增加,手动管理流程将很快变得痛苦,我不会那样做.

However, as you note right at the beginning, it all amounts to using ValidationNel[String, Unit], where Unit, "no data of interest" is the interesting part. If means you will handle the actual data separately. You may win a little bit here, and that little bit is avoiding the syntax of Applicative, sprinkling your code with |@| and suchlike; also, a not-often mentioned price of Monads and Co, making it easier to work with a debugger. But there is a downside, as your code grows with places where errors may occur multiplying too, managing the flow by hand will quickly become painful and I would not go that way.

通常的替代方法是例外.

The usual alternative is exceptions.

这篇关于如何在 Scala 中实现简单的验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆