if we look at Wikipedia the definition of Kleisli it seems its something complex. Sometimes it seems like Mathematicians are actively trying to make everything complex, so developers cannot easily apply it, right ? But don’t worry it’s actually simple.
if we have a two functions g,f we know how to compose them:
f1 : A→B
f2 : B→Ccomposition :A→C would be :
Func<A,C> composition =x=>f2(f1(x))
But if we have two functions that return a monad we cannot directly compose them. Because in order to use the second function we need B instead of M[B] which is the result of f1.
f1 : A→M<B>
f2 : B→M<C>what would be the composition: A→M<C> ?Func<A,M<C>> composition =x=>f2(f1(x))
does not work
This kind of monadic composition is called Kleisli composition.
if we have again the Identity Monad for simplicity lets see how would implement the Kleisi composition
if we have two functions :
//f1 : int → Monad<int>
Func<int, Monad<int>> f1 = x => new Monad<int>(x * x);//f2 : int → Monad<int>
Func<int, Monad<int>> f2 = x => new Monad<int>(2 * x);
then their composition can be done couple of ways. One way is displayed below. We could apply A to f1 : A→M[B] and get M[B] the monad of B then we could apply the f2: B→M[C] to this and get a M[M[C]] and then flatMap this with the Bind operation and get The M[C] result.
Func<int, Monad<int>> compose=a => f1(a).Map(b=>f2(b)).Bind(x=>x);
An other way to do that would be this :
Func<int, Monad<int>> composition = a => f1(a).Bind(b => f2(b));
you can try it by yourself in this online .netFiddle: