O'Reilly logo

Developing Web Applications with Haskell and Yesod by Michael Snoyman

Stay ahead with the world's most comprehensive technology and business learning platform.

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

Start Free Trial

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.

Start Free Trial

No credit card required