Applicative validation syntax

People say that Validation is Scalaz’s gateway drug, which might be accurate if you ignore the suggestion that there’s anything even remotely fun about validation. In my book, making sure that your program doesn’t choke on bad input is always a chore.

Applicative validation is at least a step in the right direction—it makes it easier to write less code, introduce fewer bugs, and draw clearer lines between data models and validation logic. Suppose for example that we have the following case class in Scala:

Suppose also that we have a form with three fields that we want to use to create instances of Foo. We receive input from this form as strings, and we want to be sure that these strings have certain properties.

Using Scalaz 7, we can write the following:

Now we can write a method that will lift our constructor into the ValidationNel applicative functor and apply it to our input (after running each piece of that input through the appropriate validator):

See my Stack Overflow answer here for some additional discussion of this syntax (and applicative functors more generally) in the context of validation.

We can confirm that this method works as expected:

Unfortunately the |@| syntax is kind of ugly—especially compared to Haskell, where we’d write the following:

It gets even worse if you have more than twelve fields, as this Stack Overflow question points out. In that case you have to fall back to calling ap (or, equivalently, Scalaz’s version of <*>) directly, which looks like this:

It’s horrible—the arguments are in the wrong order and there are parentheses everywhere.

When I saw that question this morning, I started wondering about ways that Shapeless might be able to make the situation a little better. The rest of this post is a sketch of some quick experiments in that direction.

First of all, it’s not too hard to write a general operator for lifting functions of arbitrary arity into any applicative functor:

Now we can factor out the lifting part of our definition of validateFoo in a way that’s (arguably) a little nicer:

One (possibly) more interesting approach would be to write a method that would take a constructor and a heterogeneously-typed list of validators and then build our top-level validation function for us. This also isn’t too hard. First for some more general-purpose machinery:

And now we can write the following:

Which we can use in exactly the same way as our original validateFoo above.

I’m not sure I want to argue that this approach is in any sense better than going with the applicative builder syntax that comes with Scalaz (when that’s an option), but it does give an example of how we can use Shapeless to add flexibility to an existing library without a lot of boilerplate.