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.