This is some work I did as part of my master's thesis . It's an extension to GHC's STM implementation. The main idea is to introduce a new primitive function
atomicallyWithIO :: STM a -> (a -> IO b) -> IO b
Like the existing atomically operation, atomicallyWithIO performs an STM computation. Additionally, it takes a finalizer, which is an arbitrary I/O action that can depend on the result of the STM computation, and combines it with the transaction in such a way that:
- The finalizer is only performed if the STM transaction is guaranteed to commit.
- The STM transaction only commits if the finalizer finishes without raising an exception.
A detailed specification, including an operational semantics, as well as a discussion of the implementation, can be found in chapter 2 of my thesis .
I actually did this work quite some time ago, and even announced it on the mailing list  to some positive feedback, but then never got around to actually submitting a patch. Last week Charles Strahan wrote me on GitHub and got me motivated again, so here I am :)
I'm submitting a code review to Phabricator right now and will link it to this ticket.