How to implement simple validation in Scala

徘徊边缘 提交于 2019-12-11 02:31:33

问题


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

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

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)

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


回答1:


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 ::: / ++.

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

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.



来源:https://stackoverflow.com/questions/28925040/how-to-implement-simple-validation-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!