:
- "push " - , . "", GHC. , pushStack .
- popStack , Stack MVar. , , " ".
- takeMVar putMVar withMVar modifyMVar. , , .
, MVars, , .
StackData - (), (). , MVar , .
type Lock = MVar ()
type Some a = (a, [a])
data StackData a = Full !(Some a)
| Empty !Lock
data Stack a = Stack { stack :: MVar (StackData a) }
pop s = do
x <- modifyMVar (stack s) $ \ sd ->
case sd of
Empty lock -> do
return (Empty lock, Left lock)
Full (a, []) -> do
lock <- newEmptyMVar
return (Empty lock, Right a)
Full (a, (b:bs)) -> return (Full (b, bs), Right a)
case x of
Left lock -> do
withMVar lock return
pop s
Right a -> return a
push s a = modifyMVar_ (stack s) $ \ sd ->
case sd of
Empty lock -> do
tryPutMVar lock ()
evaluate Full (a,[])
Full (b, bs) -> do
xs <- evaluate (b:bs)
evaluate (Full (a, xs))
. .
EDIT: push () , . "". "Restore" "modifyMVar", :
push s a = mask $ \restore -> do
mLock <- modifyMVar (stack s) $ \ sd -> restore $
case sd of
Empty lock -> do
n <- evaluate Full (a,[])
return (n, Just lock)
Full (b, bs) -> do
xs <- evaluate (b:bs)
n <- evaluate (Full (a, xs))
return (n, Nothing)
whenJust mLock $ \ lock -> tryPutMVar lock ()