important news: refocusing discussion
Ross Paterson
ross at soi.city.ac.uk
Wed Mar 29 04:59:55 EST 2006
On Tue, Mar 28, 2006 at 10:25:04AM +0100, Simon Marlow wrote:
> On 28 March 2006 00:24, Ross Paterson wrote:
> > How about STM (minus retry/orElse) and TVars as the portable
> > interface? They're trivial for a single-threaded implementation, and
> > provide a comfortable interface for everyone.
>
> It just occurred to me that STM isn't completely trivial in a
> single-threaded implementation, because exceptions have to abort a
> transaction in progress.
Almost trivial, though:
import Prelude hiding (catch)
import Control.Exception
import Data.IORef
-- The reference contains a rollback action to be executed on exceptions
newtype STM a = STM (IORef (IO ()) -> IO a)
unSTM (STM f) = f
instance Functor STM where
fmap f (STM m) = STM (fmap f . m)
instance Monad STM where
return x = STM (const (return x))
STM m >>= k = STM $ \ r -> do
x <- m r
unSTM (k x) r
atomically :: STM a -> IO a
atomically (STM m) = do
r <- newIORef (return ())
m r `catch` \ ex -> do
rollback <- readIORef r
rollback
throw ex
catchSTM :: STM a -> (Exception -> STM a) -> STM a
catchSTM (STM m) h = STM $ \ r -> m r `catch` \ ex -> unSTM (h ex) r
newtype TVar a = TVar (IORef a)
newTVar :: a -> STM (TVar a)
newTVar a = STM $ const $ do
ref <- newIORef a
return (TVar ref)
readTVar :: TVar a -> STM a
readTVar (TVar ref) = STM (const (readIORef ref))
writeTVar :: TVar a -> a -> STM ()
writeTVar (TVar ref) a = STM $ \ r -> do
oldval <- readIORef ref
modifyIORef r (writeIORef ref oldval >>)
writeIORef ref a
More information about the Haskell-prime
mailing list