global counters

Jan de Wit Jan de Wit" <jwit@cs.uu.nl
Thu, 20 Dec 2001 10:13:21 +0100


> basically, i want a function getVar :: () -> String which returns a new
> string every time.  i tried this:
>
> > curVarId = newSTRef (0 :: Integer)
> >
> > {-# NO-INLINE newVar -}
> >
> > newVar = \_ -> ('\0' : show x)
> >     where y = unsafePerformIO (stToIO curVarId)
> >           x = unsafePerformIO $ stToIO $
> >   do x <- readSTRef y
> >      writeSTRef y (x + 1)
> >      return x
>
> and in ghci it works wonderfully, but when i actually compile, all i get
> is "\NUL0".
>
> what's the proper way to write this?

I think (haven't tested this one) you should write (modulo layout):
| curVarIdRef :: IORef Integer
| curVarIdRef = unsafePerformIO $ newIORef (0 :: Integer)
|
| {-# NO-INLINE newVar -}
|
| newVar :: () -> String
| newVar = \_ -> ('\0' : show x) where
|   x = unsafePerformIO $
|     do x <- readIORef curVarIdRef
|           writeIORef curVarIdRef (x + 1)
|           return x

Because in your original version, curVarId allocates a new reference to 0
every time newVar is called.

Hope this works, Jan de Wit