Skip to content

Instantly share code, notes, and snippets.

@mchaver
Created January 8, 2016 03:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mchaver/7549b0e144b130191fd4 to your computer and use it in GitHub Desktop.
Save mchaver/7549b0e144b130191fd4 to your computer and use it in GitHub Desktop.
Short example of how to use IORef. IORef is not a global value, it is a container that must be passed, but its contents can be changed.
module Main where
import Data.IORef
-- runhaskell tutorial1.hs
{-
create IORef with newIORef
newIORef :: a -> IO (IORef a)
IORef is a container that has something of type a
the value in IORef can change
writeIORef :: IORef a -> a -> IO ()
change the value of the object in IORef
must be the same type
modifyIORef :: IORef a -> (a -> a) -> IO ()
apply a pure function to the value in IORef
get value out of IORef
readIORef :: IORef a -> IO a
notice that it returns IO
the value is removes its IORef wrapper
and it gains an IO one, you have to be in IO to use IORefs
-}
main :: IO ()
main = do
-- create a new IORef
stringRef <- newIORef $ ""
string1 <- readIORef stringRef
print string1
-- change the value inside stringRef
writeIORef stringRef "A"
string2 <- readIORef stringRef
print string2
-- now it is apparent that the value inside of stringRef has changed
module Main where
import Data.IORef
import System.IO
-- runhaskell tutorial2.hs
-- to access an IORef you still have to pass it manually
-- and to alter it you need to be in an IO monad, since
-- modifyIORef and writeIORef all return IO ()
step :: IORef Int -> IO ()
step counter = do
-- pass a function (a->a) that modifies the value inside
-- the IORef
modifyIORef counter (+1)
return ()
infiniteLoop :: IORef Int -> IO ()
infiniteLoop counter = do
-- wait for user to push enter
_ <- getLine
c <- readIORef counter
print c
step counter
infiniteLoop counter
{- counter is not a global var
brokenInfiniteLoop does not know that counter exists
brokenInfiniteLoop :: IO ()
brokenInfiniteLoop = do
_ <- getLine
c <- readIORef counter
print c
step counter
brokenInfiniteLoop
-}
main = do
counter <- newIORef 0
infiniteLoop counter
-- run infinitely, wait for user to push enter before showing incremented counter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment