haskellioref

Behaviour of IORef in Haskell


In GHCI (version 9.0.1), the following gives back what I would expect:

ghci> import Data.IORef
ghci> ref <- newIORef ([] :: [Int])
ghci> modifyIORef ref (1:)
ghci> readIORef ref
[1]

But when I try the same thing this way:

ghci> import Data.IORef
ghci> ref = newIORef ([] :: [Int])
ghci> ref >>= \r -> modifyIORef r (1:) 
ghci> ref >>= readIORef
[]

An empty list is returned, as if the modify never happened. Why does this happen? Shouldn't the output be the same?


Solution

  • When you write ref = newIORef ..., the type of ref is IO (IORef [Int]) (because that is the type that newIORef returns). Every time you execute that IO action (by including it in an IO action that GHCI evaluates), you get a new IORef.

    In contrast, when you write ref <- newIORef, you are asking GHCI to execute the IO action, yielding an IORef [Int], and save the resulting IORef to the variable ref. Then all the later operations you perform on it are performed on the same IORef.