ST monad and monad tranformers

Reid Barton rwbarton at math.harvard.edu
Mon Feb 2 14:50:10 EST 2009


On Mon, Feb 02, 2009 at 06:03:15PM +0100, Josef Svenningsson wrote:
> Hi Tyson,
> 
> 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:

> import Control.Monad
> import Control.Monad.Trans
> import Control.Monad.ST.Trans
> 
> data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show
> 
> instance Monad Tree where
>   return = Leaf
>   Leaf a >>= k = k a
>   Branch l r >>= k = Branch (l >>= k) (r >>= k)
> 
> foo :: STT s Tree Integer
> foo = do
>   x <- newSTRef 0
>   y <- lift (Branch (Leaf 1) (Leaf 2))
>   when (odd y) (writeSTRef x y)
>   readSTRef x
> 
> main = do
>   print $ runST foo
>   let Branch _ (Leaf x) = runST foo
>   print x

prints

Branch (Leaf 1) (Leaf 1)
0

Evaluating the thunk in the left branch affects the value seen in the
right branch.  In general a monad transformer version of ST would need
to duplicate its state for each branch when used in conjunction with a
nondeterminism monad like Tree, which would make it not really
different from State, I think.

Regards,
Reid


More information about the Glasgow-haskell-users mailing list