## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

No credit card required

# Types

I purposely started with the ErrorT transformer, as it is one of the simplest for this inversion mechanism. Unfortunately, others are a bit more complicated. Take for instance, ReaderT. It is defined as ```newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }```. If we apply `runReaderT` to it, we get a function that returns a monadic value. So we’re going to need some extra machinery to deal with all that stuff. And this is when we leave Kansas behind.

There are a few approaches to solving these problems. In the past, I implemented a solution using type families in the `neither` package. Anders Kaseorg implemented a much more straightforward solution in `monad-peel`. And for efficiency, in `monad-control`, Bas van Dijk uses CPS (continuation passing style) and existential types.

### Note

The code taken from monad-control actually applies to version 0.2.0.3 changed things just a bit, by making the state explicit with an associated type, and generalizing `MonadControlIO` to `MonadBaseControl`, but the concepts are still the same.

The first type we’re going to look at is:

````type` `Run` `t` `=` `forall` `n` `o` `b``.` `(``Monad` `n``,` `Monad` `o``,` `Monad` `(``t` `o``))` `=>` `t` `n` `b` `->` `n` `(``t` `o` `b``)`
```

That’s incredibly dense, so let’s talk it out. The only “input” data type to this thing is t, a monad transformer. A Run is a function that will then work with any combination of types n, o, and b (that’s what the forall means). n and o are both monads, while b is a simple value contained by them.

The lefthand side of the Run function, `t n b`, is our ...

## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

No credit card required