Haskell IORef State
Haskell IORef state is a changeable box that lives inside IO. It lets an IO program keep a value that later steps can read and update.
Write replaces the boxed value
The box starts at 10. Writing 20 replaces that value.
import Data.IORef
main :: IO ()
main = do
ref <- newIORef 10
a <- readIORef ref
writeIORef ref 20
b <- readIORef ref
print (a, b)Modify changes the boxed value
The box starts at 7. Adding 3 and then doubling gives 20.
import Data.IORef
main :: IO ()
main = do
ref <- newIORef 7
modifyIORef ref (+3)
modifyIORef ref (*2)
v <- readIORef ref
print vA helper can bump a shared box
One helper adds 1 to any box it is given. Calling it twice leaves 2 in the box.
import Data.IORef
bump :: IORef Int -> IO ()
bump r = modifyIORef r (+1)
main :: IO ()
main = do
ref <- newIORef 0
bump ref
bump ref
v <- readIORef ref
print vExample
import Control.Monad (forM_)
import Data.IORef
main :: IO ()
main = do
count <- newIORef 0
total <- newIORef 0
forM_ [4,5,6] (\x -> modifyIORef count (+1) >> modifyIORef total (+x))
c <- readIORef count
t <- readIORef total
print (c, t)Key points
- IORef: an IORef is a box that holds one value a program can change.
- New: newIORef makes a box holding a starting value.
- Read: readIORef reads the value currently in the box.
- Write: writeIORef replaces the value in the box.
- Modify: modifyIORef changes the value by applying a function to it.
In this example, the program makes two boxes for a count and a total. It walks three numbers and bumps the count once and adds each number to the total. It prints the final count and total together.
Note
an IORef only works inside IO, so pure code cannot read or change it.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What is the difference between writeIORef and modifyIORef?