I am trying to treat a ReaderT X IO
monad as IO to achieve the following:
-- this is the monad I defined:
type Game = ReaderT State IO
runGame :: State -> Game a -> IO a
runGame state a = runReaderT a state
readState :: Game State
readState = ask
-- some IO action, i.e. scheduling, looping, etc.
ioAction :: IO a -> IO ()
ioAction = undefined
-- this works as expected, but is rather ugly
doStuffInGameMonad :: Game a -> Game ()
doStuffInGameMonad gameAction = do
state <- readState
liftIO $ ioAction $ runGame state gameAction
ioAction
for example is scheduling another IO action in intervals. Unwrapping the Game
monad every time seems a bit cumbersome -- and feels wrong.
What I am trying to achieve instead is:
doStuffInGameMonad :: Game a -> Game ()
doStuffInGameMonad gameAction = ioAction $ gameAction
My intuition tells me, this should be possible somehow, because my Game
monad is aware of IO. Is there a way to implicitly convert/unlift the Game
monad?
Please excuse if my terminology is not correct.