module Control.Monad.Adaptive.CircularList(
CircularList,
circularList,
val,
update,
next,
previous,
insert,
delete) where
import Control.Monad.Adaptive.Ref
circularList :: Ref m r => a -> m (CircularList m r a)
val :: Ref m r => CircularList m r a -> m a
next :: Ref m r => CircularList m r a -> m (CircularList m r a)
update :: Ref m r => CircularList m r a -> a -> m ()
previous :: Ref m r => CircularList m r a -> m (CircularList m r a)
insert :: Ref m r => CircularList m r a -> a -> m (CircularList m r a)
delete :: Ref m r => CircularList m r a -> m ()
data CircularList m r a = CL (r (CircularList m r a,a,CircularList m r a))
| DummyCL (m a)
deCL (CL l) = l
circularList a = do
r <- newRef undefined
let l = CL r
writeRef r (l,a,l)
return l
get :: Ref m r => CircularList m r a ->
m (CircularList m r a, a,CircularList m r a)
get = readRef . deCL
set :: Ref m r => CircularList m r a ->
(CircularList m r a, a,CircularList m r a) -> m ()
set = writeRef . deCL
update l a = do
(p,_,n) <- get l
set l (p,a,n)
val l = (\ (p,a,n) -> a) `fmap` get l
next l = (\ (p,a,n) -> n) `fmap` get l
previous l = (\ (p,a,n) -> p) `fmap` get l
insert l a = do
(p,b,n) <- get l
n' <- CL `fmap` newRef (l,a,n)
set l (p,b,n')
nl <- next n'
(_,nb,nn) <- get nl
set nl (n',nb,nn)
return n'
delete l = do
(p,_,n) <- get l
(pp,a,_) <- get p
set p (pp,a,n)
(_,a',nn) <- get n
set n (p,a',nn)