
I will just translate your example from Norvell's DIY state monad to GHC's ST monad. As you noticed, GHC's ST monad begins with an "empty" state and you use some commands to add state variables as you go. This means the translation is not straightforward. I hope you still get the gist of it. Your hunch is correct: Norvell's applyST becomes GHC's runST. Your example uses two state variables: a Char and an Int, paired up as a tuple. Below, I use one state variable of type (Char,Int) for that, as hinted by your first attempt at the translation. foo and bar will each need to take a parameter --- the reference to the state variable, due to the reference business. testfunc = do r <- newSTRef ('x',0) foo r bar r (c,n) <- readSTRef r return n foo r = do (c,n) <- readSTRef r writeSTRef r ('a', n+1) bar r = do (c,n) <- readSTRef r writeSTRef r (c,n+2) tryTestFunc = runST testfunc