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 call.

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.

Cheers,
Greg


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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to