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
_______________________________________________
Haskell mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell

Reply via email to