Showing posts with label Scalaz. Show all posts
Showing posts with label Scalaz. Show all posts

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.

Monday, 30 April 2012

Validation without Scalaz

[2012-05-01 Update: added snippets showing case where check functions are in a collection.]
[2012-05-06 Update: links now point to new branch, 'simple' instead of 'master' one.]

So it's the desire to implement checks (that inputs are valid) in a more functional way (than by throwing exceptions) that's one of the main motivations for adopting Scalaz, it seems.

I've encountered evidence for this on at least a couple of occasions: first, at Chris Marshall's talk about practical uses of Scalaz in the financial industry at Skills Matter, and most recently, at Noel Welsh's Blue Eyes presentation at Scala Days 2012.

Having played around with the standard Scala library's scala.Either myself recently, after Noel's talk, I got to asking a few people why more use wasn't made of that.

Apparently, this is because Either can't be used in for comprehensions involving multiple generators (since it lacks a flatMap method), and because there's no support for accumulating bad results.

So I've since taken a closer look, and discovered that it can in fact be used in said for comprehensions, and that with the help of this twenty-odd line type-class, can also be used to accumulate bad results!

The challenge I set myself was to try to rewrite Chris's (very helpful) Nightclubs (Github) gist without using Scalaz. This I succeeded in doing, as shown here.

The trick is to use the Either's right: RightProjection method in for comprehensions. So this...


...becomes this:


And Chris's code for accumulate bad values...



...may be rewritten using an implicit method provided by the type class:


Finally, if the checks happen to be in a collection, this...


...becomes this:



Please help yourself to the type class, which is maintained in a Github project called scala-either-extras.

Comments welcome.