Haskell newIORef readIORef writeIORef
Mutable variables are not used often in Haskell, but there is time that you need to
use mutable variables in your code. There are many ways to create mutable variables.
Here is how to use mutable variables in Haskell
1. Create a mutable variable with newIORef
2. Modify or write the variable with modifyIORef
3. Read the variable whatever the new value is inside with readIORef
var <- newIORef 2
x <- readIORef var
print x
writeIORef var 100
x1 <- readIORef var
print x1
-------------------------------------------------------------------
import Data.IORef
ref <- newIORef 0
replicateM_ 4 $ modifyIORef ref (+5)
readIORef ref >>= print -- output 20
ref <- newIORef 1
replicateM_ 4 $ modifyIORef ref (+5)
readIORef ref >>= print -- output 21
-- modify (Set Int)
set <- newIORef Set.empty
modifyIORef set (Set.insert 2)
set <- readIORef set
Haskell Mutable Loop, it is wrong way to do thing
total <- newIORef 0
let loop i =
if i > 100
then do
readIORef total
else do
modifyIORef total (+1)
pp $ "i=" <<< i
loop (i + 1)
loop 1
Mutable Record in Haskell
1. Create a record
2. Create new IORef record
3. Read the record from IORef
4. Write a new record to the IORef
data MyRec = MyRec{age :: Int, name :: String} deriving (Show)
let rec = MyRec{age = 10, name = "Tristen"}
x <- newIORef rec
s <- readIORef x
print $ age s ++ " " ++ name s
writeIORef x MyRec{age = 20, name = "Tristen"}
State Var Example
-- SEE: Example $sp/StateVar/src/Main.hs
makeStateVarFromPtr :: Storable a => Ptr a -> StateVar a
makeStateVarFromPtr p = makeStateVar (peek p) (poke p)
main = do
pp "State Var"
when True $ do
fw "state var"
p <- malloc :: IO (Ptr Int)
let v = makeStateVarFromPtr p
v $= 11
v $~ (+20)
n <- Data.StateVar.get v
print $ "First n=" ++ show n
pp "OK"
v $~ (+100)
n <- Data.StateVar.get v
print $ "Second n=" ++ show n
Software Transaction Memory STM in Haskell
-- SEE: Example $sp/haskell-stm/src/Main.hs
import Control.Concurrent.STM
import Control.Concurrent.STM.TVar
wallet <- newTVarIO 0
atomically $ do
myCash <- readTVar wallet
writeTVar wallet (myCash + 10)
newAmount <- readTVar wallet
getPaid :: TVar a -> IO()
getPaid wallet = forever $ do
threadDelay 1000 * 1000
atomically $ modifyTVar wallet (+1)
print "I earned a dollar"