import Control.Monad.Reader data Connection = Connection data Builder = Builder data Context = Context { connection :: Connection, builder :: Builder } no_action :: Connection -> Builder -> Int -> IO Int no_action _ _ i = return (i + 1) type CBIO b = ReaderT Context IO b liftCBIO :: (Connection -> Builder -> a -> IO b) -> (a -> CBIO b) liftCBIO f v = do context <- ask liftIO (f (connection context) (builder context) v) cbio_no_action = liftCBIO no_action runWithInIO = flip runReaderT main = do i <- runWithInIO (Context Connection Builder) $ do a <- cbio_no_action 20 liftIO $ putStrLn "Halfway through!" b <- cbio_no_action 30 return (a + b) putStrLn $ show i