Currently, Haskell have transactional arrays in "Control.Concurrent.STM.TArray" implemented as "Array i (TVar e)" which is array of transactional variables. But what if I need to place an array into TVar itself? This is something like "TVar (IOArray i e)", but with ability to read/write array elements inside an STM transaction, and then commit changes with "atomically".
I've tried to make up this arrays in the following way: > {-# LANGUAGE MagicHash #-} > {-# LANGUAGE UnboxedTuples #-} > {-# OPTIONS_GHC -fno-cse #-} > module Data.Vector.STM > ( TVector > , newTVector > , newTVectorIO > , readTVector > , readTVectorIO > , writeTVector > ) where > import GHC.Conc > import GHC.Prim > import GHC.Types (Int(..), IO(..)) > data MutableArray a = MutableArray (MutableArray# RealWorld a) > data TVector a = TVector (TVar# RealWorld (MutableArray a)) > stm = STM > {-# NOINLINE stm #-} > newTVector :: Int -> a -> STM (TVector a) > newTVector (I# i#) x = stm $ \s1# -> > case newArray# i# x s1# of { (# s2#, a# #) -> > case newTVar# (MutableArray a#) s2# of { (# s3#, t# #) -> > (# s3#, (TVector t#) #) }} > newTVectorIO :: Int -> a -> IO (TVector a) > newTVectorIO (I# i#) x = IO $ \s1# -> > case newArray# i# x s1# of { (# s2#, a# #) -> > case newTVar# (MutableArray a#) s2# of { (# s3#, t# #) -> > (# s3#, (TVector t#) #) }} > readTVector :: TVector a -> Int -> STM a > readTVector (TVector t#) (I# i#) = stm $ \s1# -> > case readTVar# t# s1# of { (# s2#, (MutableArray a#) #) -> > case readArray# a# i# s2# of { (# s3#, a #) -> > (# s3#, a #) }} > readTVectorIO :: TVector a -> Int -> IO a > readTVectorIO (TVector t#) (I# i#) = IO $ \s1# -> > case readTVarIO# t# s1# of { (# s2#, (MutableArray a#) #) -> > case readArray# a# i# s2# of { (# s3#, a #) -> > (# s3#, a #) }} > writeTVector :: TVector a -> Int -> a -> STM () > writeTVector (TVector t#) (I# i#) x = stm $ \s1# -> > case readTVar# t# s1# of { (# s2#, (MutableArray a#) > #) -> > case writeArray# a# i# x s2# of { s3# -> > case writeTVar# t# (MutableArray a#) s3# of { s4# -> > (# s4#, () #) }}} It seems like it works, but I'm in doubt about it's correctness. Unfortunately, I don't know much about STM mechanics, so I'm asking Cafe users (you :-) for help. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe