These days (this week-end) I wanted to put some work on a Neo4J Rest driver that I'm writing for Play 2.0 in Scala.
The only thing I wanted, actually, is to have the current embryo more functional. I mean I was throwing exceptions (frightening... huh!).
Since this driver is meant to be fully asynchronous (man... it's http, it MUST be) and non-blocking (Play's philosophy), I was hardly using the
Promisething via the use of the WS api of Play.
This is the kind of thing I've got (briefly):
def getNode(id:Int) : Promise[Neo4JElement]
Neo4JElementstands for the wrapper of all Neo4J Rest response (Json). Hence, it can be either a Failure response (Json with stacktrace and message), it can be a Node, or .... throw an Exception (br...) when the service crashed (f.i.).
Hmm, not so intuitive and goes against the functional paradigm that orders: "you can't ever introduce side-effects, boy!". An exception that blows in my face, is one side effect (head-aches, ...).
Diego Validation to the rescue
Validation is a very simple thing, it holds either a value, either an error...
Ok, why not just
Eitherthen. Actually, you're right but
Validationthat I took in the ScalaZ library contains a lot of thing very helpful for the purpose of validation. But if you worry it, just replace
Eitherin your mind from here.
Now, here is the
def getNode(id:Int) : Promise[Validation[Aoutch, Node]]
Isn't it more intuitive? For sure, you get back our relevant type in the signature :
So far, so good now what the heck is
Aoutch: something that hurts... and what could hurt a runtime execution... exceptions yeah! Thus,
Aoutchis just a shortcut for
Either[NonEmptyList[String], Failure]. We can see that we represent with one single type an unexpected exception and a failure (missing node f.i.).
If you don't know what a Monad is, from here thing about a structure that can evolve in a for-comprehension (in scala it must implement
Validationare Monads. And their used one over the another. But what really interests us is the leaf of the chain
Node. That introduced some boilerplate code when you try to sequence actions like that:
See... yes we have to skip the first level (validation) to be able to work with the meaningful objects.
But still that we can extract some pattern... no?
The pattern that we can extract is kind of two-level composition. I did this composition my-self trying to figure out what we'll be possible.
It was successful but, I've have to introduce a new type and a new method, that was like a
So I asked on StackOverflow ^^ (and it was my first question, yeepeee). You can find it here. So I want explain how I did, because the question explains it. But the real question was, is there a well-known functional construction for this problem?.
Thanks to @purefn, I knew that it was the case!
It was time to use Monad Transformer.
Briefly (and very roughly), a Monad Transformer is a construction that is able to transform a
P[_], where M, N, P are Monads.
I won't explain here how it does, because it would be long, but here is a good link (you've to understand Haskell a bit, sorry).
With the help of such transformer, you'll get you back the opportunity to use for-comprehension... with the wrapped-twice type as bound value.
Here is the the transformer for our
And how we can now link nodes:
Awesome! No! We get 3 async and non-blocking calls, totally typed checked and resistant to exceptions and failures... In 5 lines.
At the SO question, @purefn tolds me that scalaz 7 (snapshot) is defining (fully) this kind of Validation Transformer.
Why didn't I used it, yet:
- I'm trying to use not Snapshot (not a good reason, but still)
- In order to use
ValidationT, I'll have first to create an instance of the Type Class
Monad. Because the
flatMapsignature needs it in the context.
I love functional (even if I'm still learning -- back -- the basis ^^)