[Haskell] IORef sharing

Rodney D Price rodprice at raytheon.com
Mon Oct 27 18:27:26 EDT 2008


I'm trying to understand how an IORef (MVar, TVar) might be
shared between separate instances of function closures.
I've defined a function `count` that returns a function with
an IORef "inside",

> count :: IORef Int -> Int -> IO (Char -> IO Int)
> count io i = do
>   writeIORef io i
>   return (\c -> if c == 'a'
>                 then modifyIORef io (+1) >> readIORef io
>                 else readIORef io)

Now I define an IORef and a couple of counters that share
the IORef,

> iio :: IO (IORef Int)
> iio = newIORef 0
> ic1 = do { io <- iio ; count io 0 }
> ic2 = do { io <- iio ; count io 0 }

I expected to see the counters sharing the IORef, so that
executing `counter1` below would print "1,1,2,3".  Instead,
it prints "1,0,1,2".

> counter1 = do
>   c1 <- ic1
>   c2 <- ic2
>   c1 'a' >>= print
>   c2 'b' >>= print
>   c2 'a' >>= print
>   c1 'a' >>= print

However, if I create the two counters inside the same do
block, I get the result I expected, "1,1,2,3".

> counter2 = do
>   io <- iio
>   c1 <- count io 0
>   c2 <- count io 0
>   c1 'a' >>= print
>   c2 'b' >>= print
>   c2 'a' >>= print
>   c1 'a' >>= print

So apparently my mental picture of an IORef as a pointer
to a value is wrong.  I need a new mental picture.  What's
going on here?

Thanks,
-Rod


More information about the Haskell mailing list