
I've found this example. counter :: IO Int counter = unsafePerformIO $ newIORef 0 getUnique :: IO Int getUnique = atomicModifyIORef counter $ \x -> let y = x + 1 in (y, y) Which I ran, and I know works in as much as calling getUnique multiple times results in an incremented value. I have two things I'm failing to see about it. 1) Why doesn't counter return a newIORef with value 0, every time getUnique is called there by producing a value of 1 no matter how often getUnique is called? Is this this because it returns an IORef so counter just becomes bound to the value it first returns and it's not evaluated again and the IORef is just returned, or something else? 2) Why does the lambda return a tuple and why does the example return the same value in both positions i.e. (y,y)? The only thing I could think of is because the name has "atomic" that the values in the tuple is being used for some sort of compare and swap,CAS. P.S I didn't find http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-IORef.html enlightening on the matter and I know that example is not great because the atomicModifyIORef is lazy so could lead to stackoverflow as that doc. page says... Thanks