7

In scalaz Kleisli[M[_], A, B] is a wrapper of A => M[B], which allows composition of such functions. For instance, if M[_] is monad I can compose Kleisli[M, A, B] and Kleisli[M, B, C] with >=> to get Kleisli[M, A, C].

In a nutshell, Kleisli provides fancy andThens depending on M. Is it correct ? Are there other benefits of using Kleisli?

Michael
  • 41,026
  • 70
  • 193
  • 341

1 Answers1

10

Here are two benefits as examples—I'm sure you could come up with others.

First, it can be useful to abstract over different arrows, such as Kleisli[M, ?, ?] and ? => ?. For example, I can write a generic function that will apply an endomorphism a certain number of times.

def applyX10[Arr[_, _]: Category, A](f: Arr[A, A]) =
  List.fill(10)(Endomorphic(f)).suml

Now I can use this on e.g. Int => Int or Kleisli[Option, Int, Int]:

val f = (_: Int) + 1

val k = Kleisli.kleisli[Option, Int, Int] {
  case i if i % 2 == 0 => Some(i * 3)
  case _ => None
}

And then:

scala> applyX10(f).run(1)
res0: Int = 11

scala> applyX10[=?>, Int](k).run(2)
res1: Option[Int] = Some(118098)

(Note that A =?> B is just an alias for Kleisli[Option, A, B].)

Second, the fact that Kleisli[F, ?, ?] has a monad instance if F does can also be useful. See for example my answer here for a demonstration of how you can use monadic composition with ReaderT, which is just an alias for Kleisli.

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • Thanks. I will try to _grok_ it as follows: (1) `Kleisli` in general as an abstraction over different arrows (2) special cases: e.g. `ReaderT`, reader monad, etc. – Michael Mar 17 '15 at 06:47
  • Well, for a monad `M`, `Kleisli[M, ?, ?]` is _an_ arrow. – Travis Brown Mar 17 '15 at 12:07