处理对象的字段的验证=>要么/ TRY(阶2.10)/ ValidationNEL(scala

2019-08-17 04:59发布

假设使用生成器模式构建的对象。

此构建图案将包含build方法侧重于字段的验证,然后在转换到目标类型。

该验证可以采用以下方式实现:

  • Either[FailureObject, TargetObject]键入
  • Try[TargetObject]从斯卡拉2.10新功能)
  • Validation[FailureObject, TargetObject]ValidationNEL[FailureObject, TargetObject]从scalaz库

我读到的主要优势之一ValidationEither类型是Validation可以累积失败“开箱即用”。

但对于“新”的Try呢? 我注意到, Try了“一元”的方法开箱即用也一样, mapflatMap等...什么真正用任何一种类型的不帮助缺少Projection

因此,我想像每个字段的验证方法返回Try[FieldType]和更精确地,在任何故障的情况下,一个Try[SpecificFieldExceptionType] ; 此嵌套一个包含String消息字段和可能在整个被累积一个rootCause复制字段build方法。

使用Scala的2.10,可以或应该Try的做法取代scalaz验证库进行简单的验证像生成器模式涉及?

**编辑* ***

通过阅读Try的源代码,这听起来是Try不能积累一些例外,因而是面向快速失败的。 即使Try.flatMap返回potentential以前的失败,因此不会有积累的概念:

def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]

论相反ValidationNEL ,处理积累功能。

任何确认?

Answer 1:

有权衡:

  • scalaz.Validation能够积累式的错误E给出Semigroup[E]实例。 它适用于用作Applicative ,如:

     (fragileFoo |@| fragileBar) { case (foo, bar) => doSomething(foo, bar) } 

    它确实有mapflatMap方法,对偏Success的一面,所以你可以在方便地使用它for -comprehension。 然而,没有Monad为它定义的实例,因此它不能在任何高阶的东西被使用(例如,你不能用单子变压器使用它)。 这个缺点似乎并不像它会成为你的问题,但。

  • scalaz.\/ ,你不提,并形成Monad (再次,朝偏向Right侧)。 但作为一个使用时Applicative ,它不为失败的积累Validation呢。

  • util.Try类似于scalaz.\/ ,专门用于Throwable 。 虽然再次没有误差的累积,它确实有错误恢复的概念。 但是,对于您的“构建者模式”的使用情况,好像这可能不是非常有用。

  • 最后, util.Either是不值得考虑,相对于其他三个选项:因为它不是朝着一侧或另一偏置,你必须明确和一贯要求的leftright ,你想做些什么,每次一元投影。

我最好的猜测是,您的具体情况, scalaz.Validation是最合适的选择。



文章来源: Best way to handle object's fields validation => Either / Try (scala 2.10) / ValidationNEL (scalaz)