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"