The question says it all, really. I know a (Scala) Monad looks like this:
trait Monad[M[_]] {
def pure[A](a : A) : M[A]
def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}
What does a Monad Transformer look like? And what are they used for?
EDIT. Consider the following REPL session: if a monad transformer somehow decorates a monad with reader capabilities (or vice versa)
Let’s say I just want to use replicateM from Scalaz;
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))
Now let’s say, rather than having an Option[Int], I need to read an Int value from a File:
scala> val f = (_ : java.io.File) => some(1)
f: (java.io.File) => Option[Int] = <function1>
So, I can treat this reader, as if it was a Monad?
scala> ReaderT(f).replicateM[List](2)
<console>:16: error: value replicateM is not a member of scalaz.ReaderT[Option,java.io.File,Int]
ReaderT(f).replicateM[List](2)
^
Err, no.
Apologies if this all seems stupid, I’m just trying to understand what lovely goodness my wrapping the File => Option[Int] in a ReaderT can actually buy me.
Monad transformers are type functions that when applied to a monad type, generate a new monad, that combines the behavior of both components.
E.g. in the
xmonadwindow manager, the computations run inside:that is, a
Readercomposed with aStateand anIOmonad.Readergives access to read-only memoryStateprovides a form of read-write stateIOallows arbitrary external effectsNote that monad transforms are thus higher-rank types. They take a monadic type of kind (
* -> *), and yield a new type of that kind.As always, the Haskell wiki has some useful content:
Where it all began: