Search code examples
haskellyesodmonad-transformers

Is Yesod's Handler Monad an instance of MonadBaseControl IO?


I would like to use the withResource :: MonadBaseControl IO m => Pool a -> (a -> m b) -> m b from the Data.Pool library in my handler code. I am trying to determine if Handler is an instance of MonadBaseControl IO, but I'm having a hard time finding the exact place that Handler is defined.

Is Yesod's Handler Monad (as created by mkYesodData) an instance of MonadBaseControl IO or can it easily be made into one?


Solution

  • No, Handler does not have a MonadBaseControl IO instance.

    However, it's basically a reader, so it's not too difficult to write one.

    Assuming you're using the scaffolded site, the following should work. Add some extensions and imports to the top of Foundation:

    import Control.Monad.Base
    import Control.Monad.Trans.Control
    import Yesod.Core.Types (HandlerFor(..))
    

    In some convenient place after the mkYesodData statement, add the instances:

    instance MonadBase IO Handler where
      liftBase = liftIO
    instance MonadBaseControl IO Handler where
      type StM Handler a = a
      liftBaseWith ioAct = HandlerFor $ \handlerData ->
        ioAct (\handlerAct -> unHandlerFor handlerAct handlerData)
      restoreM = return
    

    I have no idea if what you're generally trying to do is a good idea or not, but that should get things to type-check.