[Haskell-cafe] why cannot i get the value of a IORef variable ?

Gregory Crosswhite gcross at phys.washington.edu
Thu Oct 22 02:23:44 EDT 2009

For clarity, one trick that uses "unsafePerformIO" which you may have  
seen posted on this list earlier today is the following way of  
creating a globally visible IORef:

import Data.IORef
import System.IO.Unsafe

*** counter = unsafePerformIO $ newIORef 0 ***

next = do
   modifyIORef counter (+1)
   readIORef counter

The key line has been starred;  this created a counter IORef that  
"next" could access without having to be explicitly given it on each  

Personally, though, I never use this approach because it creates a  
race condition.  Because Haskell is lazy, "counter" will not be  
evaluated until the first time that it is accessed.  If two threads  
access it at the same time before it has been evaluated, then in GHC  
there are conditions under which they could both evaluate it and  
create a new IORef simultaneously, resulting in each thread  
effectively ending up with its own counter variable when you  
specifically wanted a globally shared counter variable.

This is why I personally use the ReaderT monad if I want to implicitly  
share a global IORef, rather than using this trick.


On Oct 21, 2009, at 10:50 PM, Colin Paul Adams wrote:

>    zaxis> thank you! In fact i really donot understand
>    zaxis> "unsafePerformIO" very much !
> Then all you have to understand is - never use it!
> -- 
> Colin Adams
> Preston Lancashire
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list