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