Monday 7 May 2012

Validating multiple values at once (without Scalaz)

[2012-05-08 Update: now using uncurried case-class constructor in final example.]

This is useful if you want to pass them to a function (and only do so if they're all valid).

The initial version of the EitherExtras type class, introduced in my last post, has now been endowed with the necessary support.

Here are some examples to show how to use it.

The following code, which would rely on methods a and b throwing an exception in the event of failure...

...may be rewritten so as to use scala.Either instead, like so:

Note the following:

  • EitherExtras itself is no longer a type class, and may now be mixed into the self type, as here
  • it has an abstract type, L, to be assigned the type of the contents of the Left result, when validating multiple values at once
  • f is required to be curried
  • fast applies it in a fail-fast manner: if method a returns a Left, that will be the result (and b is not called)
  • conversely, slow would still call b, and return a Left containing a List, possible including the invalid result from that as well
  • <*> was chosen as the operator, for conformity with the Haskell language, since we're now using Either as an applicative functor.
Here are some implementations and corresponding results.

Please see the usingEitherApp to run this code yourself.

The next example shows how the above may be used together with the implicit methods for applying multiple checks to a single value (that EitherExtras provides already).

Note that the two original methods (check, checkAndMap) have now become four (fastCheck, fastCheckAndMap, slowCheck, slowCheckAndMap), so as to allow either fail-fast or fail-slow application of the checks, as described above.

Please see usingEitherApp2 for implementations and results, and to run the example yourself.

The final example is slightly less minimalist and abstract, and involves a case class.

Note how the uncurried case-class constructor is converted to the required curried form. (Alternatively, case classes may be created using a curried constructor, although then, only the first parameter is mentioned by toString.)

For implementations and results, and to run this example yourself, please see usingEitherApp3.

Finally, I should mention that this latest effort was prompted (and the last example inspired) by a comment made by Chris Marshall in response to my previous post.

Again, help yourself to this new version of EitherExtras, which now occupies the master branch of the scala-either-extras project on Github - the original version has been moved to a new branch called simple.

Comments welcome.

No comments:

Post a Comment