简体   繁体   English

Scala 验证 - 偏右

[英]Scala validation - Right-biased Either

At last Scala 2.12 has Right-biased Either.最后 Scala 2.12 偏右。 I heard it can be used for validation purpose but I cannot imagine this.我听说它可以用于验证目的,但我无法想象这一点。 I am not able to find good example.我找不到好的例子。
Could somebody explain me how this monad could help me with validation?有人能解释一下这个 monad 如何帮助我进行验证吗? Also what other use-cases could be covered by this enhanced Either?此外,此增强的“任一”还可以涵盖哪些其他用例?

Either[A, B] be it right biased or not is great for validation/exception handling. Either[A, B]无论是否有偏见,都非常适合验证/异常处理。 Making it right biased makes it easier for us to compose operations over it.使其正确偏置使我们更容易对其进行组合操作。

Let's say we want to validate an object, what forms can a validation method take?假设我们要验证一个对象,验证方法可以采用什么形式? The simplest form would be a predicate, a method taking an arbitrary object and returning a Bool :最简单的形式是谓词,一种采用任意对象并返回Bool

sealed trait Base
case class Foo(I: Int)
case class Bar(s: String)

def isValid(b: Base): Bool = b match {
  case Foo(i) => i > 18
  case Bar(s) => s.length > 5
}

This will work, but may not be enough at times.这会起作用,但有时可能还不够。 What if this is a user facing API, and we want to be explicit about the possible errors with the received object such that the user will quickly understand what went wrong?如果这是一个面向用户的 API,并且我们希望明确接收到的对象可能存在的错误,以便用户能够快速了解​​出了什么问题,该怎么办?

What if instead of returning a Bool, we'll either return a list of errors or return the valid object itself?如果不是返回 Bool,而是返回错误列表或返回有效对象本身会怎样? This will allow us to further compose:这将使我们能够进一步编写:

def validate(b: Base): Either[List[String], Base] = b match {
  case Foo(i) => if (i > 18) Right(b) else Left(List("i must be greater than 18"))
  case Bar(s) => if (s.length > 5) Right(b) else Left(List("s must be longer than 5 chars"))
}

Now we can map over it:现在我们可以映射它:

val foo = Foo(42)
val result = validate(foo).map { case Foo(i) => s"yay, valid foo number: $i" } 
result match {
  case Left(errors) => println(s"Something went wrong: ${errors.mkString(", ")}")
  case Right(msg) => println(msg)
}

We gain two things.我们得到两件事。 First is the ability to compose validate with other operations and defer error handling, and the second is explicit errors.首先是能够将验证与其他操作组合起来并延迟错误处理,其次是显式错误。 We could even take this further and make these errors typed, allowing the user to match on them and apply error handling for each use case, but that's for another time.我们甚至可以更进一步,让这些错误类型化,允许用户匹配它们并为每个用例应用错误处理,但那是另一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM