I'm currently building a new API, and one of the functions it currently provides is:

inSpan :: Tracer -> Text -> IO a -> IO a

I'm looking to move that Tracer into a monad, giving me a signature more like

inSpan :: MonadTracer m => Text -> m a -> m a

The implementation of inSpan uses bracket , which means I have two main options:

class MonadUnliftIO m => MonadTracer m

or

class MonadMask m => MonadTracer m

But which should I prefer? Note that I'm in control of all the types I've mentioned, which makes me slightly lean towards MonadMask as it doesn't enforce IO at the bottom (that is, we could perhaps have a pure MonadTracer instance).

Is there anything else I should consider?