title: What are good Haskell conventions for managing deeply nested bracket patterns?
body: <p>I am currently working with Haskell bindings to a HDF5 C library.  Like many C libraries, this one uses many pointers in its functions calls.</p>
  
  <p>The usual "best practice" Haskell functions for allocating and releasing C resources follow the <a href="http://www.haskell.org/haskellwiki/Bracket_pattern" rel="noreferrer">bracket pattern</a>, like <code>alloca</code>, <code>withArray</code>, etc.  In using them, I often enter several nested brackets.  For instance, here is a small excerpt for HDF5 bindings:</p>
  
  <pre><code>selectHyperslab rID dName = withDataset rID dName $ \dID -&gt; do
    v &lt;- withDataspace 10 $ \dstDS -&gt; do
      srcDS &lt;- c'H5Dget_space dID
      dat &lt;- alloca3 (0, 1, 10) $ \(start, stride, count) -&gt; do
        err &lt;- c'H5Sselect_hyperslab srcDS c'H5S_SELECT_SET start stride count nullPtr
        -- do some work ... 
        return value
  
  alloca3 (a, b, c) action =
    alloca $ \aP -&gt; do
      poke aP a
      alloca $ \bP -&gt; do
        poke bP b
        alloca $ \cP -&gt; do
          poke cP c
          action (aP, bP, cP)
  </code></pre>
  
  <p>In the code above, the nested brackets are bracket functions I wrote <code>withDataset</code>, <code>withDataspace</code>, and <code>alloca3</code>, which I wrote to prevent the bracket nesting from going another 3 levels deep in the code.  For C libraries with lots of resource acquisition calls and pointer arguments, coding with the standard bracket primitives can get unmanageable (which is why I wrote <code>alloca3</code> to reduce the nesting.)</p>
  
  <p>So generally, are there any best practices or coding techniques to help reduce the nesting of brackets when needing to allocate and deallocate many resources (such as with C calls)?  The only alternative I have found is the <a href="https://www.fpcomplete.com/user/snoyberg/library-documentation/resourcet" rel="noreferrer">ResourceT</a> transformer, which from the tutorial looks like it is designed to make interleaving resource acquire/release possible, and not to simplify the bracket pattern.</p>