This is the first post in a series of two(?) about Scalaz’s Kleisli construction.
This post will cover the basic usage of Kleisli. A yet to be written post will cover different operators that are defined on Kleisli.
First a caveat: I’m not a seasoned Scalaz developer with years and years of experience. This post represents my current understanding of the topic. Feel free to drop me a mail if you have suggestions for improvements so I can learn more!
The code examples are available at github.
Kleisli is used for functional functional composition. In this post we will investigate Kleisli by looking a couple of basic examples. We will also try to understand the implementation of Keisli in Scalaz.
So in the word’s of Ramones:
Let’s say that we have two different functions:
We could combine the two functions like so:
I.e. we first invoke the addOne function and then invokes the double function with the result from the first computation.
This is another way to do the same thing:
This is called functional composition, i.e. we compose a new function composedFunction
from the existing addOne
and double
functions.
Here’s another example:
For this to work the types must lineup, i.e. the type of the output from the first function must match the type on the input of the next function. In the second example above addOne
produces an Int
, toAs
expects an Int
as input and hence the types lines up!
This is an example where functional composition is not working:
The code above contains three functions that is used to validate that content of Person
follows some rules. It would be nice if we could compose a single validator
function from the three different lesser validation functions.
But alas, the types doesn’t line up since nameValidator produces an Either[String, Person]
and the cityValidator
expects a Person
as input.
This is where Kleisli comes in. The Kleisli gives support to compose functions when the results of the function invocation is Monadic. Examples of Monads are plentiful: List
, Option
, Either
to name a few. Both the nameValidator
and cityValidator
in the example above are examples where we can use Kleisli.
So let’s compose nameValidation
, cityValidator
and salaryValidator
into a single validation function:
The composed function is used like this:
Alternative syntaxes for the functional composition above are:
Yes, flatMap can be used to the same effect like this:
Or like this:
However this is a post about Kleisli, so let’s get back to that.
Now that we know what Kleisli can be used for, let’s take a look at some code from the Scalaz library:
We start by looking at the constructor of the Kleisli class. We can see that it accepts functions of the following kind: run: A => M[B]
. We can also see that it only accepts a M that has a type parameter M[_]
. This mean that the following code will not compile:
This since a Person
don’t accepts any type parameters. This however will work perfectly fine:
This since that List accepts a type parameter. The conclusion is that Kleisli will only work for functions that results in a type constructor.
The next thing from the Kleisli class I would like to highlight is >=>
and it’s alias andThen
:
Well, on second thought to understand the code above we probably should look at the signature for bind
first of all:
So it looks like the signature for bind
corresponds to the signature of flatMap
. Let’s do an experiment with bind
and Either
:
Looks like flatMap
to me!
By the way, since Bind
only accepts constructs with one type parameter and Either[+A, +B]
has two, we have to partially apply one of the type parameters like this: [({type f[x] = Either[String, x]})#f]
. The syntax for this in Scala could be better :-).
Ok, so now that we knows what bind
does let’s take a look at >=>
again:
We can see that it creates a new Kleisli with a function that will do a flatMap when we eventually chooses to invoke the Kleisli.
Maybe a concrete example is in place:
If we further substitutes a
(i.e. invokes the Kleisli) with validPerson we get:
In other words we are essentially building a chain of flatMap’s.
Finally i would like to highligt:
As we can see the only thing it does is to wrap the in argument in a Kleisli and the call >=>
.
This gives us the ability (as already shown above) to compose a function using this simple syntax:
And that’s it, this is the basics of Kleisli, it is nothing but a construction to get the ability to compose functions!
We have shown that Kleisli can be used to compose functions when the result from the function invokation is Monadic. We have also investigated the Scalaz code that makes this work.
We have concluded that we can get the same effect using flatMap
but with a less concise syntax:
In the next post which is yet to be written we will investigate different operators that are defined on Kleisli.
The code examples are available at github.