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