module Control.Concurrent.STM.Stack (
Stack,
stackNew,
stackPush,
stackPeek,
stackTryPeek,
stackPop,
stackTryPop,
stackIsEmpty,
stackSize,
)
where
import Control.Concurrent.STM.TVar
import Control.Monad.STM
import Numeric.Natural
data Stack a = Stack (TVar [a])
stackNew :: STM (Stack a)
stackNew = do
items <- newTVar []
return (Stack items)
stackPush :: Stack a -> a -> STM ()
stackPush (Stack itemsVar) item = do
items <- readTVar itemsVar
writeTVar itemsVar (item:items)
stackTryPeek :: Stack a -> STM (Maybe a)
stackTryPeek (Stack itemsVar) = do
items <- readTVar itemsVar
if null items
then return Nothing
else return (Just (head items))
stackPeek :: Stack a -> STM a
stackPeek (Stack itemsVar) = do
items <- readTVar itemsVar
if null items
then retry
else return (head items)
stackTryPop :: Stack a -> STM (Maybe a)
stackTryPop (Stack itemsVar) = do
items <- readTVar itemsVar
if null items
then return Nothing
else do writeTVar itemsVar (tail items)
return (Just (head items))
stackPop :: Stack a -> STM a
stackPop (Stack itemsVar) = do
items <- readTVar itemsVar
if null items
then retry
else do writeTVar itemsVar (tail items)
return (head items)
stackIsEmpty :: Stack a -> STM Bool
stackIsEmpty (Stack itemsVar) = do
items <- readTVar itemsVar
if null items then return True else return False
stackSize :: Stack a -> STM Natural
stackSize (Stack itemsVar) = do
items <- readTVar itemsVar
return (fromIntegral (length items))