-- |
-- Module     : Simulation.Aivika.Trans.DoubleLinkedList
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- An imperative double-linked list.
--
module Simulation.Aivika.Trans.DoubleLinkedList 
       (DoubleLinkedList, 
        listNull, 
        listCount,
        newList, 
        listInsertFirst,
        listAddLast,
        listRemoveFirst,
        listRemoveLast,
        listRemove,
        listRemoveBy,
        listContains,
        listContainsBy,
        listFirst,
        listLast,
        clearList,
        freezeList) where 

import Data.Maybe
import Data.Functor

import Control.Monad

import Simulation.Aivika.Trans.Ref.Base
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Event

-- | A cell of the double-linked list.
data DoubleLinkedItem m a = 
  DoubleLinkedItem { forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal  :: a,
                     forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev :: Ref m (Maybe (DoubleLinkedItem m a)),
                     forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext :: Ref m (Maybe (DoubleLinkedItem m a)) }
  
-- | The 'DoubleLinkedList' type represents an imperative double-linked list.
data DoubleLinkedList m a =  
  DoubleLinkedList { forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead :: Ref m (Maybe (DoubleLinkedItem m a)),
                     forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail :: Ref m (Maybe (DoubleLinkedItem m a)), 
                     forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize :: Ref m Int }

-- | Test whether the list is empty.
listNull :: MonadRef m => DoubleLinkedList m a -> Event m Bool
{-# INLINABLE listNull #-}
listNull :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m Bool
listNull DoubleLinkedList m a
x =
  do Maybe (DoubleLinkedItem m a)
head <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) 
     case Maybe (DoubleLinkedItem m a)
head of
       Maybe (DoubleLinkedItem m a)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
       Just DoubleLinkedItem m a
_  -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
    
-- | Return the number of elements in the list.
listCount :: MonadRef m => DoubleLinkedList m a -> Event m Int
{-# INLINABLE listCount #-}
listCount :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m Int
listCount DoubleLinkedList m a
x = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)

-- | Create a new list.
newList :: MonadRef m => Simulation m (DoubleLinkedList m a)
{-# INLINABLE newList #-}
newList :: forall (m :: * -> *) a.
MonadRef m =>
Simulation m (DoubleLinkedList m a)
newList =
  do Ref m (Maybe (DoubleLinkedItem m a))
head <- forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing 
     Ref m (Maybe (DoubleLinkedItem m a))
tail <- forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
     Ref m Int
size <- forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef Int
0
     forall (m :: * -> *) a. Monad m => a -> m a
return DoubleLinkedList { listHead :: Ref m (Maybe (DoubleLinkedItem m a))
listHead = Ref m (Maybe (DoubleLinkedItem m a))
head,
                               listTail :: Ref m (Maybe (DoubleLinkedItem m a))
listTail = Ref m (Maybe (DoubleLinkedItem m a))
tail,
                               listSize :: Ref m Int
listSize = Ref m Int
size }

-- | Insert a new element in the beginning.
listInsertFirst :: MonadRef m => DoubleLinkedList m a -> a -> Event m ()
{-# INLINABLE listInsertFirst #-}
listInsertFirst :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> a -> Event m ()
listInsertFirst DoubleLinkedList m a
x a
v =
  do Int
size <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)
     forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x) (Int
size forall a. Num a => a -> a -> a
+ Int
1)
     Maybe (DoubleLinkedItem m a)
head <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x)
     case Maybe (DoubleLinkedItem m a)
head of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         do Ref m (Maybe (DoubleLinkedItem m a))
prev <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            Ref m (Maybe (DoubleLinkedItem m a))
next <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            let item :: Maybe (DoubleLinkedItem m a)
item = forall a. a -> Maybe a
Just DoubleLinkedItem { itemVal :: a
itemVal = a
v, 
                                               itemPrev :: Ref m (Maybe (DoubleLinkedItem m a))
itemPrev = Ref m (Maybe (DoubleLinkedItem m a))
prev, 
                                               itemNext :: Ref m (Maybe (DoubleLinkedItem m a))
itemNext = Ref m (Maybe (DoubleLinkedItem m a))
next }
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item
       Just DoubleLinkedItem m a
h ->
         do Ref m (Maybe (DoubleLinkedItem m a))
prev <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            Ref m (Maybe (DoubleLinkedItem m a))
next <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef Maybe (DoubleLinkedItem m a)
head
            let item :: Maybe (DoubleLinkedItem m a)
item = forall a. a -> Maybe a
Just DoubleLinkedItem { itemVal :: a
itemVal = a
v,
                                               itemPrev :: Ref m (Maybe (DoubleLinkedItem m a))
itemPrev = Ref m (Maybe (DoubleLinkedItem m a))
prev,
                                               itemNext :: Ref m (Maybe (DoubleLinkedItem m a))
itemNext = Ref m (Maybe (DoubleLinkedItem m a))
next }
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
h) Maybe (DoubleLinkedItem m a)
item
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item

-- | Add a new element to the end.
listAddLast :: MonadRef m => DoubleLinkedList m a -> a -> Event m ()
{-# INLINABLE listAddLast #-}
listAddLast :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> a -> Event m ()
listAddLast DoubleLinkedList m a
x a
v =
  do Int
size <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)
     forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x) (Int
size forall a. Num a => a -> a -> a
+ Int
1)
     Maybe (DoubleLinkedItem m a)
tail <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x)
     case Maybe (DoubleLinkedItem m a)
tail of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         do Ref m (Maybe (DoubleLinkedItem m a))
prev <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            Ref m (Maybe (DoubleLinkedItem m a))
next <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            let item :: Maybe (DoubleLinkedItem m a)
item = forall a. a -> Maybe a
Just DoubleLinkedItem { itemVal :: a
itemVal = a
v, 
                                               itemPrev :: Ref m (Maybe (DoubleLinkedItem m a))
itemPrev = Ref m (Maybe (DoubleLinkedItem m a))
prev, 
                                               itemNext :: Ref m (Maybe (DoubleLinkedItem m a))
itemNext = Ref m (Maybe (DoubleLinkedItem m a))
next }
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item
       Just DoubleLinkedItem m a
t ->
         do Ref m (Maybe (DoubleLinkedItem m a))
prev <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef Maybe (DoubleLinkedItem m a)
tail
            Ref m (Maybe (DoubleLinkedItem m a))
next <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
            let item :: Maybe (DoubleLinkedItem m a)
item = forall a. a -> Maybe a
Just DoubleLinkedItem { itemVal :: a
itemVal = a
v,
                                               itemPrev :: Ref m (Maybe (DoubleLinkedItem m a))
itemPrev = Ref m (Maybe (DoubleLinkedItem m a))
prev,
                                               itemNext :: Ref m (Maybe (DoubleLinkedItem m a))
itemNext = Ref m (Maybe (DoubleLinkedItem m a))
next }
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
t) Maybe (DoubleLinkedItem m a)
item
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
item

-- | Remove the first element.
listRemoveFirst :: MonadRef m => DoubleLinkedList m a -> Event m ()
{-# INLINABLE listRemoveFirst #-}
listRemoveFirst :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m ()
listRemoveFirst DoubleLinkedList m a
x =
  do Maybe (DoubleLinkedItem m a)
head <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) 
     case Maybe (DoubleLinkedItem m a)
head of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         forall a. HasCallStack => [Char] -> a
error [Char]
"Empty list: listRemoveFirst"
       Just DoubleLinkedItem m a
h ->
         do Int
size <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x) (Int
size forall a. Num a => a -> a -> a
- Int
1)
            Maybe (DoubleLinkedItem m a)
head' <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
h)
            case Maybe (DoubleLinkedItem m a)
head' of
              Maybe (DoubleLinkedItem m a)
Nothing ->
                do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) forall a. Maybe a
Nothing
                   forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) forall a. Maybe a
Nothing
              Just DoubleLinkedItem m a
h' ->
                do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
h') forall a. Maybe a
Nothing
                   forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
head'

-- | Remove the last element.
listRemoveLast :: MonadRef m => DoubleLinkedList m a -> Event m ()
{-# INLINABLE listRemoveLast #-}
listRemoveLast :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m ()
listRemoveLast DoubleLinkedList m a
x =
  do Maybe (DoubleLinkedItem m a)
tail <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) 
     case Maybe (DoubleLinkedItem m a)
tail of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         forall a. HasCallStack => [Char] -> a
error [Char]
"Empty list: listRemoveLast"
       Just DoubleLinkedItem m a
t ->
         do Int
size <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)
            forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x) (Int
size forall a. Num a => a -> a -> a
- Int
1)
            Maybe (DoubleLinkedItem m a)
tail' <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
t)
            case Maybe (DoubleLinkedItem m a)
tail' of
              Maybe (DoubleLinkedItem m a)
Nothing ->
                do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) forall a. Maybe a
Nothing
                   forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) forall a. Maybe a
Nothing
              Just DoubleLinkedItem m a
t' ->
                do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
t') forall a. Maybe a
Nothing
                   forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
tail'

-- | Return the first element.
listFirst :: MonadRef m => DoubleLinkedList m a -> Event m a
{-# INLINABLE listFirst #-}
listFirst :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m a
listFirst DoubleLinkedList m a
x =
  do Maybe (DoubleLinkedItem m a)
head <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x)
     case Maybe (DoubleLinkedItem m a)
head of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         forall a. HasCallStack => [Char] -> a
error [Char]
"Empty list: listFirst"
       Just DoubleLinkedItem m a
h ->
         forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
h

-- | Return the last element.
listLast :: MonadRef m => DoubleLinkedList m a -> Event m a
{-# INLINABLE listLast #-}
listLast :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m a
listLast DoubleLinkedList m a
x =
  do Maybe (DoubleLinkedItem m a)
tail <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x)
     case Maybe (DoubleLinkedItem m a)
tail of
       Maybe (DoubleLinkedItem m a)
Nothing ->
         forall a. HasCallStack => [Char] -> a
error [Char]
"Empty list: listLast"
       Just DoubleLinkedItem m a
t ->
         forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
t

-- | Remove the specified element from the list and return a flag
-- indicating whether the element was found and removed.
listRemove :: (Eq a, Functor m, MonadRef m) => DoubleLinkedList m a -> a -> Event m Bool
{-# INLINABLE listRemove #-}
listRemove :: forall a (m :: * -> *).
(Eq a, Functor m, MonadRef m) =>
DoubleLinkedList m a -> a -> Event m Bool
listRemove DoubleLinkedList m a
x a
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
listRemoveBy DoubleLinkedList m a
x (forall a. Eq a => a -> a -> Bool
== a
v)

-- | Remove an element satisfying the specified predicate and return
-- the element if found.
listRemoveBy :: MonadRef m => DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
{-# INLINABLE listRemoveBy #-}
listRemoveBy :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
listRemoveBy DoubleLinkedList m a
x a -> Bool
p = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop
  where loop :: Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop Maybe (DoubleLinkedItem m a)
item =
          case Maybe (DoubleLinkedItem m a)
item of
            Maybe (DoubleLinkedItem m a)
Nothing   -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
            Just DoubleLinkedItem m a
item ->
              do let f :: Bool
f = a -> Bool
p (forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
item)
                 if Bool -> Bool
not Bool
f
                   then forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
item) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop
                   else do Int
size <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x)
                           Maybe (DoubleLinkedItem m a)
prev <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
item)
                           Maybe (DoubleLinkedItem m a)
next <- forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
item)
                           forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
x) (Int
size forall a. Num a => a -> a -> a
- Int
1)
                           case (Maybe (DoubleLinkedItem m a)
prev, Maybe (DoubleLinkedItem m a)
next) of
                             (Maybe (DoubleLinkedItem m a)
Nothing, Maybe (DoubleLinkedItem m a)
Nothing) ->
                               do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) forall a. Maybe a
Nothing
                                  forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) forall a. Maybe a
Nothing
                             (Maybe (DoubleLinkedItem m a)
Nothing, head' :: Maybe (DoubleLinkedItem m a)
head'@(Just DoubleLinkedItem m a
item')) ->
                               do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
item') forall a. Maybe a
Nothing
                                  forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
head'
                             (tail' :: Maybe (DoubleLinkedItem m a)
tail'@(Just DoubleLinkedItem m a
item'), Maybe (DoubleLinkedItem m a)
Nothing) ->
                               do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
item') forall a. Maybe a
Nothing
                                  forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) Maybe (DoubleLinkedItem m a)
tail'
                             (Just DoubleLinkedItem m a
prev', Just DoubleLinkedItem m a
next') ->
                               do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
prev') (forall a. a -> Maybe a
Just DoubleLinkedItem m a
next')
                                  forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
next') (forall a. a -> Maybe a
Just DoubleLinkedItem m a
prev')
                           forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
item)

-- | Detect whether the specified element is contained in the list.
listContains :: (Eq a, Functor m, MonadRef m) => DoubleLinkedList m a -> a -> Event m Bool
{-# INLINABLE listContains #-}
listContains :: forall a (m :: * -> *).
(Eq a, Functor m, MonadRef m) =>
DoubleLinkedList m a -> a -> Event m Bool
listContains DoubleLinkedList m a
x a
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
listContainsBy DoubleLinkedList m a
x (forall a. Eq a => a -> a -> Bool
== a
v)

-- | Detect whether an element satisfying the specified predicate is contained in the list.
listContainsBy :: MonadRef m => DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
{-# INLINABLE listContainsBy #-}
listContainsBy :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> (a -> Bool) -> Event m (Maybe a)
listContainsBy DoubleLinkedList m a
x a -> Bool
p = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
x) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {m :: * -> *}.
MonadRef m =>
Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop
  where loop :: Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop Maybe (DoubleLinkedItem m a)
item =
          case Maybe (DoubleLinkedItem m a)
item of
            Maybe (DoubleLinkedItem m a)
Nothing   -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
            Just DoubleLinkedItem m a
item ->
              do let f :: Bool
f = a -> Bool
p (forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
item)
                 if Bool -> Bool
not Bool
f
                   then forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemNext DoubleLinkedItem m a
item) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (DoubleLinkedItem m a) -> Event m (Maybe a)
loop
                   else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
item)

-- | Clear the contents of the list.
clearList :: MonadRef m => DoubleLinkedList m a -> Event m ()
{-# INLINABLE clearList #-}
clearList :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m ()
clearList DoubleLinkedList m a
q =
  do forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listHead DoubleLinkedList m a
q) forall a. Maybe a
Nothing
     forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
q) forall a. Maybe a
Nothing
     forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. DoubleLinkedList m a -> Ref m Int
listSize DoubleLinkedList m a
q) Int
0

-- | Freeze the list and return its contents.
freezeList :: MonadRef m => DoubleLinkedList m a -> Event m [a]
{-# INLINABLE freezeList #-}
freezeList :: forall (m :: * -> *) a.
MonadRef m =>
DoubleLinkedList m a -> Event m [a]
freezeList DoubleLinkedList m a
x = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedList m a -> Ref m (Maybe (DoubleLinkedItem m a))
listTail DoubleLinkedList m a
x) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {m :: * -> *} {a}.
MonadRef m =>
[a] -> Maybe (DoubleLinkedItem m a) -> Event m [a]
loop []
  where loop :: [a] -> Maybe (DoubleLinkedItem m a) -> Event m [a]
loop [a]
acc Maybe (DoubleLinkedItem m a)
Nothing     = forall (m :: * -> *) a. Monad m => a -> m a
return [a]
acc
        loop [a]
acc (Just DoubleLinkedItem m a
item) = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
DoubleLinkedItem m a -> Ref m (Maybe (DoubleLinkedItem m a))
itemPrev DoubleLinkedItem m a
item) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [a] -> Maybe (DoubleLinkedItem m a) -> Event m [a]
loop (forall (m :: * -> *) a. DoubleLinkedItem m a -> a
itemVal DoubleLinkedItem m a
item forall a. a -> [a] -> [a]
: [a]
acc)