The best way to deal with checking object fields => Either / Try (scala 2.10) / ValidationNEL (scalaz)

Let an object constructed using the builder template be assumed.

This builder template will contain a build method focused on checking fields and then converting to the target type.

This check can be implemented using:

  • Either[FailureObject, TargetObject] type
  • Try[TargetObject] (new feature from Scala 2.10)
  • Validation[FailureObject, TargetObject] or ValidationNEL[FailureObject, TargetObject] from the scalaz library

I read that one of the main benefits of the Validation over Either is that Validation can accumulate out of the box crashes.

But what about the "new" Try way? I noticed that Try also has "monadic" methods like map , flatMap , etc ... which was really absent in any type without the help of Projection .

Thus, I would suggest that each field validation method returns Try[FieldType] or rather, in the event of any failure, Try[SpecificFieldExceptionType] ; it is nested, containing the String message field and the rootCause field, which can be accumulated throughout the build method.

Using Scala 2.10, can or should Try replace the scalaz authentication library for simple verification, for example, does the linker template include?

** EDIT ****

Reading the source code for Try , it sounds like Try cannot accumulate a few exceptions and, therefore, can’t navigate quickly. Even Try.flatMap returns a potential previous failure and therefore has no notion of accumulation:

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

On the contrary, ValidationNEL , which handles the accumulation function.

Any confirmation?

+6
source share
1 answer

There are tradeoffs:

  • scalaz.Validation is capable of accumulating errors of type E , taking into account the instance of Semigroup[E] . It is intended to be used as Applicative , for example:

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

    It has map and flatMap methods biased towards the Success side, so you can conveniently use it in for recognition. However, there is no Monad instance for it, so it cannot be used in any higher order materials (for example, you cannot use it with monad transformers). This flaw does not seem to be a problem for you.

  • scalaz.\/ , which you did not mention, forms a Monad (again, shifted to the Right side). But when used as Applicative it does not accumulate failures, as Validation does.

  • util.Try is similar to scalaz.\/ specialized for Throwable . Although it again lacks the accumulation of errors, it does have the concept of error recovery. However, for your use case of the "build template" it seems that this may not be very useful.

  • Finally, util.Either not worth considering, compared to the other three options: since it is not biased towards one or the other, you must explicitly and sequentially request a left or Right projection every time you want to do something monadic.

It is best to assume that scalaz.Validation is the most appropriate choice for your situation.

+11
source

All Articles