Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it just a coincidence that Kleisli, ReaderT, and Reader are the same in Scalaz

In Scalaz

  • Kleisli[F, A, B] is a wrapper for A => F[B].
  • ReaderT[F, A, B] -- reader monad transformer -- is just an alias of Kleisli[F, A, B].
  • Reader[A, B] monad is a specialization of ReaderT with identity monad Id:
    type Reader[A, B] = ReaderT[Id, A, B].

Is it just a coincidence or there are some deeper reasons that Kleisli, ReaderT, and Reader are isomorphic in Scalaz ?

like image 283
Michael Avatar asked Mar 24 '15 06:03

Michael


1 Answers

You can think of it as arriving at the same place by two different routes. On one side you start with the reader monad, which is simply a kind of wrapper for functions. Then you realize that you want to integrate this reader functionality into a larger monad with other "effects", so you create a ReaderT monad transformer. At that point it makes sense to implement your original Reader[E, ?] as ReaderT[Id, E, ?].

From the other side, you want a type to represent Kleisli arrows (i.e. functions with a monadic return type). It turns out that this is the same thing as ReaderT, so you just make that an alias.

There's nothing terribly mysterious about the "it turns out" part. It's a little like if you started out with an Addable type class for number-like things, then decide to make it more generic, and eventually end up with a type class that just provides an associative "addition-like" operation. You've reinvented Semigroup! You may still want to keep the Addable name around, though, for historical or pedagogical reasons, or just for convenience.

That's all that's happening with Reader and ReaderT—you don't need these aliases, but they can be convenient, and may help improve the clarity of your code.

like image 157
Travis Brown Avatar answered Oct 06 '22 15:10

Travis Brown