module Counter (Counter, getCounter, mkCounter, incr, get, getAndIncr) where

import Control.Concurrent.MVar
import System.IO.Unsafe

type Counter = MVar Int
{-# NOINLINE getCounter #-} 
getCounter :: Counter
getCounter = unsafePerformIO (newMVar 0) --(newMVar [0..])

mkCounter :: Int -> IO Counter
mkCounter i = newMVar i
                 
get :: Counter -> IO Int
get c = readMVar c

incr :: Counter -> IO ()
incr c = do i <- takeMVar c
            let next = i+1
            seq next (putMVar c next)

getAndIncr :: Counter -> IO Int
getAndIncr c = do old <- get c
                  incr c
                  return old