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 ?