I'm trying to create a monad transformer for a future project, but unfortunately, my implementation of the Monad typeclasse's (>>=) function doesn't work.
First of all, here is the underlying monad's implementation :
newtype Runtime a = R {
unR :: State EInfo a
} deriving (Monad)
Here, the implementation of the Monad typeclasse is done automatically by GHC (using the GeneralizedNewtypeDeriving
language pragma).
The monad transformer is defined as so :
newtype RuntimeT m a = RuntimeT {
runRuntimeT :: m (Runtime a)
}
The problem comes from the way I instanciate the (>>=) function of the Monad typeclasse :
instance (Monad m) => Monad (RuntimeT m) where
return a = RuntimeT $ (return . return) a
x >>= f = runRuntimeT x >>= id >>= f
The way I see it, the first >>=
runs in the underlying m
monad. Thus, runRuntimeT x >>=
returns a value of type Runtime a
(right ?). Then, the following code, id >>=
, should return a value of type a
. This value is the passed on to the function f of type f :: (Monad m) => a -> RuntimeT m b
.
And here comes the type problem : the f
function's type doesn't match the type required by the (>>=) function. Jow can I make this coherent ? I can see why this doesn't work, but I can't manage to turn it into something functionnal.
Edit : The error message :
Core.hs:34:4:
Occurs check: cannot construct the infinite type: m = RuntimeT m
When generalising the type(s) for `>>='
In the instance declaration for `Monad (RuntimeT m)'
Failed, modules loaded: none.
Thank you for you help, and do not hesitate to correct any flaws in my message,
Charlie P.