Related
I am writing a function that generates a million random numbers of 1 or 0 and then counts how many 0s were generated.
import System.Random
import Control.Monad
countZeros :: Int -> IO Int
countZeros n = (length . filter (==0)) <$> (replicateM n $ randomRIO (0,1 :: Int))
countZeros' :: Int -> IO Int
countZeros' n = go n 0
where
go :: Int -> Int -> IO Int
go x acc = do
r <- randomRIO (0,1 :: Int)
case x of
0 -> pure acc
_ -> let acc' = if r == 0 then succ acc else acc
in go (pred x) acc'
when I run the functions with an input of 1000000
>λ= countZeros 1000000
499716
(0.93 secs, 789,015,080 bytes)
>λ= countZeros' 1000000
500442
(2.02 secs, 1,109,569,560 bytes)
I don't understand why the prime function is twice as slow as the other. I assumed that they are essentially doing the same thing behind the scenes.
I am using GHCi.
What am I missing?
With bang patterns, and proper compilation with -O2, the "prime" function is faster:
{-# LANGUAGE BangPatterns #-}
module Main where
import System.Random
import Control.Monad
import System.Environment
countZeros :: Int -> IO Int
countZeros n = (length . filter (==0)) <$> (replicateM n $ randomRIO (0,1 :: Int))
countZeros' :: Int -> IO Int
countZeros' n = go n 0
where
go :: Int -> Int -> IO Int
go !x !acc = do
r <- randomRIO (0,1 :: Int)
case x of
0 -> pure acc
_ -> let acc' = if r == 0 then succ acc else acc
in go (pred x) acc'
main :: IO ()
main = do
[what] <- getArgs
let n = 1000 * 1000 * 10
fun = case what of
"1" -> countZeros
"2" -> countZeros'
_ -> error "arg not a number"
putStrLn "----"
print =<< fun n
putStrLn "----"
Compiled with
$ stack ghc -- RandomPerf.hs -O2 -Wall
$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.6.3
Tests:
$ time ./RandomPerf.exe 1
----
4999482
----
real 0m3.329s
user 0m0.000s
sys 0m0.031s
$ time ./RandomPerf.exe 2
----
5001089
----
real 0m2.338s
user 0m0.000s
sys 0m0.046s
Repeating the tests gives comparable results, so this is not a fluke.
Result: the countZeros' function is significantly faster.
Using Criterion and running a proper benchmark is left as an exercise.
You probably used GHCi to assess performance, which prevents the optimizer to do its job. GHCi sacrifices proper optimization to load files faster, and be more usable in an interactive way.
These actually work in different ways from each other, at a level that matters. And both are slow.
The version using replicateM is bad because replicateM in IO can't stream its results. The entire list will be constructed at once, before filter and length get to start operating on it. The reason it's faster is that length is strict in its accumulator, so it doesn't generate a massive nested chain of thinks the way your other version does. And that's even worse for performance.
The recursive version doesn't use a strict accumulator. This means that the value it returns is a giant chain of nested thunks, holding on to all the generated entries and a bunch of indirect calls via list indexing. This is even more memory used than the filter version, because it's holding on to a bunch of closures as well as all the values. But even with that fixed, it would still be slow. Using !! just wrecks performance. It's recursive when a simple if would do the same job much more efficiently.
I am pretty new to Haskell threads (and parallel programming in general) and I am not sure why my parallel version of an algorithm runs slower than the corresponding sequential version.
The algorithm tries to find all k-combinations without using recursion. For this, I am using this helper function, which given a number with k bits set, returns the next number with the same number of bits set:
import Data.Bits
nextKBitNumber :: Integer -> Integer
nextKBitNumber n
| n == 0 = 0
| otherwise = ripple .|. ones
where smallest = n .&. (-n)
ripple = n + smallest
newSmallest = ripple .&. (-ripple)
ones = (newSmallest `div` smallest) `shiftR` 1 - 1
It is now easy to obtain sequentially all k-combinations in the range [(2^k - 1), (2^(n-k)+...+ 2^(n-1)):
import qualified Data.Stream as ST
combs :: Int -> Int -> [Integer]
combs n k = ST.takeWhile (<= end) $ kBitNumbers start
where start = 2^k - 1
end = sum $ fmap (2^) [n-k..n-1]
kBitNumbers :: Integer -> ST.Stream Integer
kBitNumbers = ST.iterate nextKBitNumber
main :: IO ()
main = do
params <- getArgs
let n = read $ params !! 0
k = read $ params !! 1
print $ length (combs n k)
My idea is that this should be easily parallelizable splitting this range into smaller parts. For example:
start :: Int -> Integer
start k = 2 ^ k - 1
end :: Int -> Int -> Integer
end n k = sum $ fmap (2 ^) [n-k..n-1]
splits :: Int -> Int -> Int -> [(Integer, Integer, Int)]
splits n k numSplits = fixedRanges ranges []
where s = start k
e = end n k
step = (e-s) `div` (min (e-s) (toInteger numSplits))
initSplits = [s,s+step..e]
ranges = zip initSplits (tail initSplits)
fixedRanges [] acc = acc
fixedRanges [x] acc = acc ++ [(fst x, e, k)]
fixedRanges (x:xs) acc = fixedRanges xs (acc ++ [(fst x, snd x, k)])
At this point, I would like to run each split in parallel, something like:
runSplit :: (Integer, Integer, Int) -> [Integer]
runSplit (start, end, k) = ST.takeWhile (<= end) $ kBitNumbers (fixStart start)
where fixStart s
| popCount s == k = s
| otherwise = fixStart $ s + 1
For pallalelization I am using the monad-par package:
import Control.Monad.Par
import System.Environment
import qualified Data.Set as S
main :: IO ()
main = do
params <- getArgs
let n = read $ params !! 0
k = read $ params !! 1
numTasks = read $ params !! 2
batches = runPar $ parMap runSplit (splits n k numTasks)
reducedNumbers = foldl S.union S.empty $ fmap S.fromList batches
print $ S.size reducedNumbers
The result is that the sequential version is way faster and it uses little memory, while the parallel version consumes a lot of memory and it is noticeable slower.
What might be the reasons causing this? Are threads a good approach for this problem? For example, every thread generates a (potentially large) list of integers and the main thread reduces the results; are threads expected to need much memory or are simply meant to produce simple results (i.e. only cpu-intensive computations)?
I compile my program with stack build --ghc-options -threaded --ghc-options -rtsopts --executable-profiling --library-profiling and run it with ./.stack-work/install/x86_64-osx/lts-6.1/7.10.3/bin/combinatorics 20 3 4 +RTS -pa -N4 -RTS for n=20, k=3 and numSplits=4. An example of the profiling report for the parallel version can be found here and for the sequential version here.
In your sequential version calling combs does not build up a list in memory since after length consumes an element it isn't needed anymore and is freed. Indeed, GHC may not even allocate storage for it.
For instance, this will take a while but won't consume a lot of memory:
main = print $ length [1..1000000000] -- 1 billion
In your parallel version you are generating sub-lists, concatenating them together, building Sets, etc. and therefore the results of each sub-task have to be kept in memory.
A fairer comparison would be to have each parallel task compute the length of the k-bit numbers in its assigned range, and then add up the results. That way the k-bit numbers found by each parallel task wouldn't have to be kept in memory and would operate more like the sequential version.
Update
Here is an example of how to use parMap. Note: under 7.10.2 I've had mixed success getting the parallelism to fire - sometimes it does and sometimes it doesn't. (Figured it out - I was using -RTS -N2 instead of +RTS -N2.)
{-
compile with: ghc -O2 -threaded -rtsopts foo.hs
compare:
time ./foo 26 +RTS -N1
time ./foo 26 +RTS -N2
-}
import Data.Bits
import Control.Parallel.Strategies
import System.Environment
nextKBitNumber :: Integer -> Integer
nextKBitNumber n
| n == 0 = 0
| otherwise = ripple .|. ones
where smallest = n .&. (-n)
ripple = n + smallest
newSmallest = ripple .&. (-ripple)
ones = (newSmallest `div` smallest) `shiftR` 1 - 1
combs :: Int -> Int -> [Integer]
combs n k = takeWhile (<= end) $ iterate nextKBitNumber start
where start = 2^k - 1
end = shift start (n-k)
main :: IO ()
main = do
( arg1 : _) <- getArgs
let n = read arg1
print $ parMap rseq (length . combs n) [1..n]
good approaches for this problem
What do you mean by this problem? If it's how to write, analyze and tune a parallel Haskell program, then this is required background reading:
Simon Marlow: Parallel and Concurrent Programming in Haskell
http://community.haskell.org/~simonmar/pcph/
in particular, Section 15 (Debugging, Tuning, ..)
Use threadscope! (a graphical viewer for thread profile information generated by the Glasgow Haskell compiler) https://hackage.haskell.org/package/threadscope
I've written a Haskell program for problem 25 on Euler. I think my program should run and return the correct answer, but it doesn't:
-- Problem25.hs
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO ()
main = do
list1 <- [1..]
list2 <- zip3 list1 list1 list1
list3 <- map funct list2
where funct u v w = (u, fib u, length1 (fib u))
putStrLn "number : " -- line 17
putStrLn $ show . head . ( dropWhile ( \(u,v,w)-> w < 1000 ) list3)
However, I get the following error:
$ ghc Problem25.hs
[1 of 1] Compiling Main ( Problem25.hs, Problem25.o )
Problem25.hs:17:3: parse error on input `putStrLn'
Why do I get the parser error? I'm in a do block, so putStrLn "number : " should be fine, right?
ok here is a version with all syntax errors removed:
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO()
main = do
putStrLn "hello"
let liste = [1..]
let liste2 = zip3 liste liste liste
let liste3 = map funct liste2
putStrLn "number : "
putStrLn $ show . head $ (dropWhile ( \(_,_,w)-> w < 1000 ) liste3)
where funct (u,_,_) = (u,fib u,length1 (fib u))
as you can see there are quite a few:
where in the middle of a do block -> this has to go to the end
<- instead of let ... = ... - remember: <- is to pull out values form computations - in this case to get an a from an IO a
one . to many in the last putStrLn (the last part with dropWhile is a value not a function)
a few places where you have to use a 3-tuple argument instead of the curried version as you choose to go with zip3 (that returns tuples)
also note that while this compiles and runs it will most likely not be a good (or even feasible) solution - I did nothing more than remove your syntax problems - to get a good solution you should first work on your fib (which does not perform very well - there are better ways to compute it - hint: search for Haskell + Fib on your fav. search engine)
here are a few remarks:
you don't need the zip3 part with 3 times the same list - you can let your funct do this work (which btw: you already do - you ignore the second and third argument)
why do you dropWhile and then take the head? (filter and head seems more natural IMO)
of course you should also rethink the funct part (notice how you never need the middle item from the tuples?)
Good luck with the rest of the exercise ;)
a bit cleaned up
I cleaned up your solution a bit:
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
solve :: Int
solve = head . filter ((>= 1000) . length1 . fib) $ [1..]
main :: IO()
main = do
putStrLn "number : "
print solve
that's still not better performance wise (that's your challange) but at least it works for 3 digits instead of 1000 (although even 10 will take quite some time with this ...)
enjoy
cannot help it
I had to try it and indeed if you define the sequence like this:
import Data.List (unfoldr)
fibs :: [Integer]
fibs = unfoldr fib (1,1)
where fib (n,m) = Just (n,(m,n+m))
(which is near to what you would usually do in a loop)
you get the answer rather quickly (4782)
of course you have to think about how to get the index to this (hint: now a zip might be a good idea)
I have a function in my main block
map anyHeavyFunction [list]
I'd like to show a progress bar during the computation process or add additional actions (pause, stop process etc.), but because map is a pure function I can't do it directly. I can guess I have to use monads, but what monad is appropriate? IO, State?
I know there is at least one library on hackage that has some pre-made monad transformers for this task, but I normally turn to the pipes package to roll my own when I need one. I am using pipes-4.0.0 it is going to be on hackage this weekend, but you can grab it form the github repo before that.
I also used terminal-progress-bar package so that it makes a nice terminal animation as well.
{-# language BangPatterns #-}
import Pipes
import qualified Pipes.Prelude as P
import Control.Monad.IO.Class
import System.ProgressBar
import System.IO ( hSetBuffering, BufferMode(NoBuffering), stdout )
-- | Takes the total size of the stream to be processed as l and the function
-- to map as fn
progress l = loop 0
where
loop n = do
liftIO $ progressBar (msg "Working") percentage 40 n l
!x <- await -- bang pattern to make strict
yield x
loop (n+1)
main = do
-- Force progress bar to print immediately
hSetBuffering stdout NoBuffering
let n = 10^6
let heavy x = last . replicate n $ x -- time wasting function
r <- P.toListM $ each [1..100] >-> P.map heavy >-> progress 100
putStrLn ""
return r
This animates:
> Working [=>.......................] 7%
> Working [=====>...................] 20%
Every update erases the last bar so it only take up one line on the terminal. Then it finishes like so:
> main
Working [=========================] 100%
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]
Here's a (kind of) simple answer that I'm not satisfied with. It is based on the fact that #shellenberg wanted to apply a heavy function on each element of a (supposedly long) list. If it suffices to move the "progress bar" once for every element of the list, then the following can be turned into a general solution.
First of all, you need to pick the monad in which you'll work. This depends on what exactly your "progress bar" is. For this discussion, let's say that the IO monad is enough and that we want to alternately display the characters -, /, | and \. You'll also (most probably) need some kind of state S (here it is only the number of elements processed so far, therefore S is Int), so the real monad used will be StateT S IO.
Suppose your original program is:
m = 100000 -- how many elements the list has
-- Your (pure) function
anyHeavyFunction :: Int -> Bool
anyHeavyFunction n =
length [1..n] + length [n+1..4217] == 4217
-- Your list
list :: [Int]
list = take m $ repeat 4217
-- The main program
main :: IO ()
main = do
let l = map anyHeavyFunction list
if and l
then putStrLn "OK"
else putStrLn "WRONG"
(Notice that, very conveniently, the heavy function takes the same time for each element of the list.)
This is how you could convert it to display the crude "progress bar":
import Control.Monad.State
import System.IO (hFlush, stdout)
m = 100000 -- how many elements the list has
k = 5000 -- how often you want to "tick"
tick :: a -> StateT Int IO a
tick x = do
s <- get
put $ s+1
when (s `mod` k == 0) $ liftIO $ do
let r = (s `div` k) `mod` 4
putChar $ "-/|\\" !! r
putChar '\b'
hFlush stdout
x `seq` return x
-- Your (pure) function
anyHeavyFunction :: Int -> Bool
anyHeavyFunction n =
length [1..n] + length [n+1..4217] == 4217
-- Your list
list :: [Int]
list = take m $ repeat 4217
-- The main program
main :: IO ()
main = do
l <- flip evalStateT 0 $ mapM (tick . anyHeavyFunction) list
if and l
then putStrLn "OK"
else putStrLn "WRONG"
An interesting point: The seq in tick forces evaluation of the result for each element of the list. This is enough, if the result has a basic type (Bool here). Otherwise, it's not clear what you would want to do -- remember Haskell is lazy!
If one wants a finer progress bar or if one is not satisfied with the assumption that one "tick" will be counted for each element of the list, then I believe it's necessary to incorporate the ticking in the logic of the heavy function. This makes it ugly... I'd like to see what kind of general solutions can be suggested to that. I'm all in for Haskell, but I think it just sucks for such things as progress bars... There's no free lunch; you can't be pure and lazy and have your progress bars made easy!
EDIT: A version which uses the ProgressBar module suggested by #Davorak. It certainly looks nicer than my rotating bar.
import Control.Monad.State
import System.ProgressBar
import System.IO (hSetBuffering, BufferMode(NoBuffering), stdout)
m = 100000 -- how many elements the list has
k = 5000 -- how often you want to "tick"
tick :: a -> StateT Int IO a
tick x = do
s <- get
put $ s+1
when (s `mod` k == 0) $ liftIO $ do
progressBar (msg "Working") percentage 40 (toInteger s) (toInteger m)
x `seq` return x
-- Your (pure) function
anyHeavyFunction :: Int -> Bool
anyHeavyFunction n =
length [1..n] + length [n+1..4217] == 4217
-- Your list
list :: [Int]
list = take m $ repeat 4217
-- The main program
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
l <- flip evalStateT 0 $ mapM (tick . anyHeavyFunction) list
if and l
then putStrLn "OK"
else putStrLn "WRONG"
The idea is the same, the drawbacks too.
You could use parMap to apply the expensive function in parallel (if the dependencies permit) and a list of TVars corresponding to each list (or chunk of) element(s) and set them once the respective function application has completed. A separate thread could check on the values and update the display (obviously some IO action would happen here).
I'm trying to create a simple counter which increases by 1 indefinitely, using IO.
I've been scratching my head ever since...
Ideally, I would like to do something along the lines of
tick = do putStr (counter)
counter + 1
where counter = 0
Then repeat the process. Then repeat the first 2 expressions. Or something along the lines of:
tick = tick'
where
counter = 1
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
Which gives me errors :/
Any help is appreciated :)
There are a couple ways to do this without using a mutable cell. You already did it with your second attempt, there's just a little error. You need to pass an initial value to the tick' function, not "set it" (haskell does not have an idea of assigning variables -- only definitions. If the line x = y appears, x will be y for its entire lifetime).
tick = tick' 0
where ...
The counter = 0 line is not doing anything; it is defining a name that is never used. The counter used in the tick' function is bound as one of its arguments (and shadows the one defined to be 0). Take some time to stare at it with that in mind, see if that makes sense.
There is a nice "higher order" way we can do this too. Essentially we want to run the infinitely long block of code:
do
print 0
print 1
print 2
...
There is a function called sequence :: [IO a] -> IO [a] (see caveat below) that will take a list of actions and construct an action. So if we can construct the list [print 0, print 1, print 2, ...] then we can pass it to sequence to build the infinitely long block we are looking for.
Take note here, this is a very important concept in Haskell: [print 0, print 1, print 2] does not print those three numbers then construct the list [0,1,2]. Instead it is itself a list of actions, whose type is [IO ()]. Making the list does nothing; it is only when you bind an action to main that it will be executed. For example, we might say:
main = do
let xs = [putStrLn "hello", getLine >> putStrLn "world"]
xs !! 0
xs !! 0
xs !! 1
xs !! 1
xs !! 0
This would twice print hello, twice get a line and print world after each, then once print hello again.
With that concept, it is easy to build the list of actions [print 0, print 1, ...] with a list comprehension:
main = sequence [ print x | x <- [0..] ]
We can simplify a bit:
main = sequence (map (\x -> print x) [0..])
main = sequence (map print [0..])
So map print [0..] is the list of actions [print 0, print 1, ...] we were looking for, then we just pass that to sequence which chains them together.
This pattern of sequence is common, and has its own mapM:
mapM :: (a -> IO b) -> [a] -> IO [b]
mapM f xs = sequence (map f xs)
Thus:
main = mapM print [0..]
About as simple as you could want.
One note about performance: since we are not using the output of these functions, we should be using sequence_ and mapM_, with trailing underscores, which are optimized for that purpose. Usually this wouldn't matter in a Haskell program because of garbage collection, but in this particular use case is kind of a special case because of various subtleties. You'll find that without the _s, the memory usage of your program gradually grows as the list of results (in this case [(),(),(),...]) is constructed but never used.
Caveat: I have given the type signatures of sequence and mapM specialized to IO, not a general monad, so that the reader does not have to learn about the orthogonal concepts of actions having types and typeclasses at the same time.
Well, let's go back to basics. What you want appears to be an IO action that when bound, prints and increments a counter? I'm going to work from that assumption.
The first thing you need is some mutable cell, since you're using the same action each time. It needs to have something mutable inside it to do something different each time it's used. I'd go with an IORef for this case.
But keeping that IORef hidden is a bit tricky. Especially since globals are bad. The best way to do it is create the IO action from inside another IO action, and then close over the IORef. Doing so gives you something like this:
import Data.IORef
mkCounter :: IO (IO ())
mkCounter = do
ref <- newIORef 0
return $ do
counter <- readIORef ref
print counter
writeIORef ref $ counter + 1
This can be used by doing something like this:
main = do
tick <- mkCounter
tick
tick
tick
Your second implementation is really close!
tick = tick'
where
counter = 1
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
Let's look at the errors for this:
Couldn't match expected type `IO b0' with actual type `a0 -> IO b0'
In the expression: tick'
Let's add some types to make sure we're getting what we want.
tick is an IO action. We don't care what value the action encapsulates, since the whole
point of it is to run forever.
tick :: IO a
Now our error is:
Couldn't match expected type `IO a' with actual type `a0 -> IO b0'
In the expression: tick'
Well, that's pretty much the same, no help there. Let's keep going.
tick' is a function that takes some integer and returns an IO action
that prints the integer and repeats tick' on the next value. Again, we don't care what
value the action encapsulates, since it runs forever.
tick' :: Int -> IO b
Wait, now that error makes sense! We defined tick = tick', but the two things have fundamentally different types. One is an action (tick) one is a function that returns an action (tick'). All we need to do is give tick' some value to get the action, so let's do that.
You'd tried to do that by saying where counter = 1 but all that did is define counter as 1 within the statement tick = tick', and since counter isn't mentioned there, it wasn't used.
When you said tick' counter | ... =, you weren't referring to the same counter as on the line above. There, you were defining another variable called counter that was only in scope within the definition of tick'.
So now our code looks like:
tick :: IO a
tick = tick' 1
where
tick' :: Int -> IO b
tick' counter | counter > 0 = do putStrLn (show counter)
tick' (counter + 1)
| otherwise = tick
If we try to compile it, ghc doesn't complain, and if we try it out in ghci it runs as desired:
% ghci
ghci> :l Tick.hs
Ok, modules loaded: Tick.
ghci> tick
1
2
3
...
25244
^C
Interrupted
ghci>
For a simple infinite counter just use recursion:
counter n = do print n
counter (n+1)
main = counter 1
Yet another way to implement tick functionality without using mutable state is to mix State and IO monad using monad transformers:
import Control.Monad.State
type Ticking a = StateT Int IO a
tick :: Ticking ()
tick = do
modify succ
get >>= liftIO . print
getCounterValue :: Ticking Int
getCounterValue = get
Then you can use it to create 'ticking' IO functions (with nuisance: IO functions here need to be prefixed with liftIO since it is now Ticking a monad not IO a):
ticking :: Ticking ()
ticking = do
liftIO $ putStrLn "Starting"
tick
tick
c <- getCounterValue
liftIO $ do
putStrLn ("Finished at " ++ show c)
putStrLn "Press any Enter to start infinite counter"
getChar
forever tick
Which can be converted into 'normal' IO using runStateT (with initial counter value):
startTicking :: Ticking a -> Int -> IO a
startTicking = evalStateT
So:
main :: IO ()
main = startTicking ticking 0
A forkIO safe version similar to Carl's answer using STM is
import Control.Concurrent.STM
import Control.Monad (replicateM_)
import Control.Monad(forever)
makeCounter :: IO (IO Int)
makeCounter = do
var <- newTVarIO 0
return $ do
atomically $ do
value <- readTVar var
modifyTVar var (+1)
readTVar var
-- a version that only counts from 1 to 10
main1:: IO ()
main1 = do
counter <- makeCounter
replicateM_ 10 $ counter >>= print
-- a version that counters forever
main2 :: IO ()
main2 = do
counter <- makeCounter
forever $ do
x<- counter
print x
main :: IO ()
main = do
counter <- makeCounter
tick<- counter
tick<- counter
print tick -- 2
Reference:
Mutable closures in Haskell and nested IO
An EXERCISE from STM tutorial
Mutable State in Haskell