As it stands, hasql supports performing transactions that end either in a rollback or a commit. Would you consider adding a third option, namely savepoints? That would allow for sane transaction isolation while letting interleaving IO in between. That is, perform this operation at the end of Hasql.Transaction.run: http://www.postgresql.org/docs/current/static/sql-savepoint.html
Then, when you continue the transaction starting from that savepoint, you'd perform a rollback to savepoint instead of an abort, if need be.
run would need to have a type like
run :: Transaction a -> ... -> IO (Either Query.ResultsError (Either (SavePoint a) a))
and Transaction should have operations for ending the transaction with a savepoint instead of a return, and for rolling back to a specific savepoint instead of just the latest one. Continuing the transaction would involve a version of run that would take the savepoint instead of the isolation, mode and connection parameters.
I'm not certain how all the kinks of an API with savepoints would go. I may try to sketch an implementation myself, yet. I'll need to familiarize myself with the new hasql version first. But I'd love to hear first whether this kind of functionality would be anything you'd care to see in hasql. I like the purity of leaving IO out of SQL transactions but I feel that there's a way to have my cake and eat it too.