Created
January 8, 2016 03:34
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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