What is the best way to manage resources in a monad stack like ExceptT a IO?
<p>For better or for worse, Haskell's popular <a href="http://haskell-servant.readthedocs.io/" rel="nofollow noreferrer">Servant</a> library has made it common-place to run code in a monad transformer stack involving <code>ExceptT err IO</code>. Servant's own handler monad is <code>ExceptT ServantErr IO</code>. As many argue, this is a somewhat <a href="https://www.fpcomplete.com/blog/2016/11/exceptions-best-practices-haskell" rel="nofollow noreferrer">troublesome monad</a> to work in since there are <em>multiple ways for failure to unroll</em>: 1) via normal exceptions from <code>IO</code> at the base, or 2) by returning <code>Left</code>.</p>

<p>As Ed Kmett's <a href="https://hackage.haskell.org/package/exceptions" rel="nofollow noreferrer"><code>exceptions</code></a> library <a href="https://hackage.haskell.org/package/exceptions-0.8.3/docs/Control-Monad-Catch.html#t:MonadMask" rel="nofollow noreferrer">helpfully clarifies</a>:</p>

<blockquote>
  <p>Continuation-based monads, and stacks such as <code>ErrorT e IO</code> which provide for multiple failure modes, are invalid instances of this [<code>MonadMask</code>] class.</p>
</blockquote>

<p>This is very inconvenient since <code>MonadMask</code> gives us access the helpful [polymorphic version of] <code>bracket</code> function for doing resource management (not leaking resources due to an exception, etc.). But in Servant's <code>Handler</code> monad we can't use it.</p>

<p>I'm not very familiar with it, but some people say that the solution is to use <code>monad-control</code> and it's many partner libraries like <code>lifted-base</code> and <code>lifted-async</code> to give your monad access to resource management tools like <code>bracket</code> (presumably this works for <code>ExceptT err IO</code> and friends as well?).</p>

<p>However, it seems that <code>monad-control</code> is <a href="http://www.yesodweb.com/blog/2014/06/exceptions-transformers" rel="nofollow noreferrer">losing favor in the community</a>, yet I can't tell what the alternative would be. Even Snoyman's recent <code>safe-exceptions</code> library uses Kmett's <code>exceptions</code> library and avoids <code>monad-control</code>.</p>

<p>Can someone clarify the current story for people like me who are trying to plow our way into serious Haskell usage?</p>