I use this trick, that unlike the previous workarounds permits concurrency and does handle the IO computation in a civilized way, that is, it permits brackets and so on:

notReallySafeButNotAsUnsafeAsUnsafeIOToSTM= safeIOToSTM

safeIOToSTM ∷  IO a → STM a
safeIOToSTM req= unsafeIOToSTM  $ do
  tv   ←  newEmptyMVar
  forkIO $ (req  ↠ putMVar  tv . Right)
          `Control.Exception.catch`
            (λ(e ∷  SomeException) → putMVar tv $ Left e )
  r ←  takeMVar tv
  case r of
   Right x → return x
   Left e → throw e

Here the IO computation is run in another thread. Even If the STM transaction is aborted, the IO computation finalizes. If the STM transaction is retried, the IO computation is re-executed, so it is up to you to take this into account depending on what you intend to do. 
If the IO computation throws an exception the STM transaction throws it. As far as I remember, this trick was used in a package time ago to do solve the problem.


2014-02-04 Bertram Felgenhauer <bertram.felgenhauer@googlemail.com>:
Rob Leslie wrote:
> I’ve run into a difficulty I’d appreciate some advice to solve.
[unsafePerformIO and bracket, within an STM transaction]

There's a long-standing bug report for this issue,

  https://ghc.haskell.org/trac/ghc/ticket/2401

So the current situation is that bracket within unsafePerformIO
(and unsafeIOToSTM) and STM transactions don't mix. I'm a bit
surprised that this doesn't bite more people.

Cheers,

Bertram
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
Alberto.