State Transformer

Jan de Wit Jan de Wit" <
Fri, 11 Jan 2002 22:28:59 +0100


> > testfunc = do
> >            r <- newSTRef ('x',0)
> >            foo r
> >            bar r
> >            (c,n) <- readSTRef r
> >            return n
> Yeap, I could do it like this myself :)
> The whole problem is with passing the 'r' as a parameter, which is
> what I'm trying to avoid. I think I already understood how to use this
> Its pretty different from the monad state I was expecting, and as far as I
> can see, to be used in distinct situations.
If I understand you correctly, you want global mutable variables, right?
This is, I believe, only possible using IORef's and unsafePerformIO.
Something like this:
| xRef :: IORef Int
| xRef = unsafePerformIO $
|  newIORef 0
| update_x :: IO ()
| update_x = do
|    x <- readIORef xRef
|    writeIORef xRef (x+1)
(Sorry for formatting, I'm using Outlook now :-)

Of course this is not very functional, nice, safe or robust under compiler
transformations (there probably should be a NOINLINE pragma there somewhere)

Another option is to use implicit variables here. I haven't tested this
approach yet, maybe somebody else on the list has? You don't need to pass
the reference around, but if you're fond of explicitly giving types for
top-level entities (as I am) you're stuck putting it in all type signatures
affected (context-ellipsis would come in handy here!!)

Cheers, Jan