ST monad and monad tranformers

Tyson Whitehead twhitehead at
Tue Feb 3 12:04:05 EST 2009

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:
> >
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url :

More information about the Glasgow-haskell-users mailing list