
On February 2, 2009 14:50:10 Reid Barton wrote:
On Mon, Feb 02, 2009 at 06:03:15PM +0100, Josef Svenningsson wrote:
I also needed something like this a while ago so I knocked up a really simple module and put it on hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/STMonadTrans
Warning! The STMonadTrans package uses State# nonlinearly, and as a result, can violate referential transparency:
So, if I understand correctly, the underlying issue is that newtype STT s m a = STT (State# s -> m (STTRet s a)) data STTRet s a = STTRet (State# s) a along with STT m >>= k = STT $ \st -> do ret <- m st case ret of STTRet new_st a -> unSTT (k a) new_st (or my equivalent versions) can multithread the "State #s" token depending on how the underlying m monad implements it's bind operator. As in your example data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show Leaf a >>= k = k a Branch l r >>= k = Branch (l >>= k) (r >>= k) things breaks as multithreading the "State# s" token is a strict no-no because it doesn't actually duplicate the underlying real word it represents. StateT doesn't have this problem as it real has a state that would then branch. I guess then, if you wanted to salvage anything out of this, you would need something like a MonadSingleThreaded class that tags single threaded monads and is a class requirement for combining with the STT monad. Is this correct? And, apart from this, is it correct that ghc optimizations can't shuffle code in such a way that things break due to the single threading of the state token through the primitive operations such as newMutVar#? Thanks -Tyson