I had an interaction on #haskell today which left me utterly confused but desiring to understand what happened. I was talking about a program in which I was using stacks of monad transformers, inspiration taken from the paper "Monad Transformers: Step by Step". So for example I wanted to combine state and error handling in a Monadic type called "Er".
data ErState = ErState StdGen
newtype Er a = Er { runEr :: ErrorT String (State ErState) a }
deriving(Monad, MonadError String, MonadState ErState)
Note that ErState holds a random generator. I had the idea to make a typeclass of monadic types that hold random generators because I'll be using them in other types all over my application. Something like
class Monad m => RandomMonad m where
getGen :: m StdGen
putGen :: StdGen -> m ()
Then I can write functions like this:
myRandoms :: (Random a, RandomMonad m) => m [a]
myRandoms = do
g <- getGen
let (g1, g2) = split g
values = randoms g1
putGen g2
return values
So then mm_freak on #haskell noticed that I had written a function with a signature like
process :: Int -> Er Int
He said, no no no functions should be agnostic with regard to data structure. It should look something like
process :: (RandomMonad m, MonadError m, MonadState m) => Int -> m Int
He then said I don't want to put StateT and ErrorT in the same newtype declaration, so it would be something like
newtype Er m a = Er { runEr :: StateT ErState m a }
On this point I'm confused. I don't know how to get from a line like the above to eventually making a type that combines error handling and state. Furthermore I need to define instances for things like MonadError. He got me started with the line
instance MonadError e m => MonadError e (Er m) where
... define throwError and catchError which I have no idea how to do ...
So where we left it, I was confused and didn't understand anything.
Rather than just getting the answers, I want to try to understand this, but I feel like I must need more background. This must be the kind of code that is in the monad transformer library. Is there a guide to understanding that somewhere?
D