{-# LANGUAGE MultiParamTypeClasses #-}
module Data.Equivalence.STT
(
Equiv
, Class
, leastEquiv
, getClass
, combine
, combineAll
, same
, desc
, remove
, equate
, equateAll
, equivalent
, classDesc
, removeClass
, values
, classes
) where
import Control.Monad.ST.Trans
import Control.Monad
import Data.Maybe
import Data.Map (Map)
import qualified Data.Map as Map
newtype Class s c a = Class (STRef s (Entry s c a))
newtype Entry s c a = Entry {forall s c a. Entry s c a -> STRef s (EntryData s c a)
unentry :: STRef s (EntryData s c a)}
data EntryData s c a
= Node {
forall s c a. EntryData s c a -> Entry s c a
entryParent :: Entry s c a,
forall s c a. EntryData s c a -> a
entryValue :: a
}
| Root {
forall s c a. EntryData s c a -> c
entryDesc :: c,
forall s c a. EntryData s c a -> Int
entryWeight :: Int,
entryValue :: a,
forall s c a. EntryData s c a -> Bool
entryDeleted :: Bool
}
type Entries s c a = STRef s (Map a (Entry s c a))
data Equiv s c a = Equiv {
forall s c a. Equiv s c a -> Entries s c a
entries :: Entries s c a,
forall s c a. Equiv s c a -> a -> c
singleDesc :: a -> c,
forall s c a. Equiv s c a -> c -> c -> c
combDesc :: c -> c -> c
}
leastEquiv
:: (Monad m, Applicative m)
=> (a -> c)
-> (c -> c -> c)
-> STT s m (Equiv s c a)
leastEquiv :: forall (m :: * -> *) a c s.
(Monad m, Applicative m) =>
(a -> c) -> (c -> c -> c) -> STT s m (Equiv s c a)
leastEquiv a -> c
mk c -> c -> c
com = do
es <- Map a (Entry s c a) -> STT s m (STRef s (Map a (Entry s c a)))
forall (m :: * -> *) a s. Applicative m => a -> STT s m (STRef s a)
newSTRef Map a (Entry s c a)
forall k a. Map k a
Map.empty
return Equiv {entries = es, singleDesc = mk, combDesc = com}
representative' :: (Monad m, Applicative m) => Entry s c a -> STT s m (Maybe (Entry s c a),Bool)
representative' :: forall (m :: * -> *) s c a.
(Monad m, Applicative m) =>
Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
representative' (Entry STRef s (EntryData s c a)
e) = do
ed <- STRef s (EntryData s c a) -> STT s m (EntryData s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s (EntryData s c a)
e
case ed of
Root {entryDeleted :: forall s c a. EntryData s c a -> Bool
entryDeleted = Bool
del} -> do
(Maybe (Entry s c a), Bool) -> STT s m (Maybe (Entry s c a), Bool)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Entry s c a)
forall a. Maybe a
Nothing, Bool
del)
Node {entryParent :: forall s c a. EntryData s c a -> Entry s c a
entryParent = Entry s c a
parent} -> do
(mparent',del) <- Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
forall (m :: * -> *) s c a.
(Monad m, Applicative m) =>
Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
representative' Entry s c a
parent
case mparent' of
Maybe (Entry s c a)
Nothing -> (Maybe (Entry s c a), Bool) -> STT s m (Maybe (Entry s c a), Bool)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Maybe (Entry s c a), Bool)
-> STT s m (Maybe (Entry s c a), Bool))
-> (Maybe (Entry s c a), Bool)
-> STT s m (Maybe (Entry s c a), Bool)
forall a b. (a -> b) -> a -> b
$ (Entry s c a -> Maybe (Entry s c a)
forall a. a -> Maybe a
Just Entry s c a
parent, Bool
del)
Just Entry s c a
parent' -> STRef s (EntryData s c a) -> EntryData s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (EntryData s c a)
e EntryData s c a
ed{entryParent = parent'} STT s m ()
-> STT s m (Maybe (Entry s c a), Bool)
-> STT s m (Maybe (Entry s c a), Bool)
forall a b. STT s m a -> STT s m b -> STT s m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Maybe (Entry s c a), Bool) -> STT s m (Maybe (Entry s c a), Bool)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Entry s c a -> Maybe (Entry s c a)
forall a. a -> Maybe a
Just Entry s c a
parent', Bool
del)
representative :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m (Entry s c a)
representative :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
representative Equiv s c a
eq a
v = do
mentry <- Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
getEntry Equiv s c a
eq a
v
case mentry of
Maybe (Entry s c a)
Nothing -> Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
mkEntry Equiv s c a
eq a
v
Just Entry s c a
entry -> do
(mrepr,del) <- Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
forall (m :: * -> *) s c a.
(Monad m, Applicative m) =>
Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
representative' Entry s c a
entry
if del
then mkEntry eq v
else case mrepr of
Maybe (Entry s c a)
Nothing -> Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
entry
Just Entry s c a
repr -> Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
repr
classRep :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Class s c a -> STT s m (Entry s c a)
classRep :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m (Entry s c a)
classRep Equiv s c a
eq (Class STRef s (Entry s c a)
p) = do
entry <- STRef s (Entry s c a) -> STT s m (Entry s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s (Entry s c a)
p
(mrepr,del) <- representative' entry
if del
then do v <- liftM entryValue $ readSTRef (unentry entry)
en <- getEntry' eq v
(mrepr,del) <- representative' en
if del then do
en' <- mkEntry' eq en
writeSTRef p en'
return en'
else return (fromMaybe en mrepr)
else return (fromMaybe entry mrepr)
mkEntry' :: (Monad m, Applicative m, Ord a)
=> Equiv s c a -> Entry s c a
-> STT s m (Entry s c a)
mkEntry' :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Entry s c a -> STT s m (Entry s c a)
mkEntry' Equiv s c a
eq (Entry STRef s (EntryData s c a)
e) = STRef s (EntryData s c a) -> STT s m (EntryData s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s (EntryData s c a)
e STT s m (EntryData s c a)
-> (EntryData s c a -> STT s m (Entry s c a))
-> STT s m (Entry s c a)
forall a b. STT s m a -> (a -> STT s m b) -> STT s m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
mkEntry Equiv s c a
eq (a -> STT s m (Entry s c a))
-> (EntryData s c a -> a)
-> EntryData s c a
-> STT s m (Entry s c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntryData s c a -> a
forall s c a. EntryData s c a -> a
entryValue
mkEntry :: (Monad m, Applicative m, Ord a)
=> Equiv s c a -> a
-> STT s m (Entry s c a)
mkEntry :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
mkEntry Equiv {entries :: forall s c a. Equiv s c a -> Entries s c a
entries = Entries s c a
mref, singleDesc :: forall s c a. Equiv s c a -> a -> c
singleDesc = a -> c
mkDesc} a
val = do
e <- EntryData s c a -> STT s m (STRef s (EntryData s c a))
forall (m :: * -> *) a s. Applicative m => a -> STT s m (STRef s a)
newSTRef Root
{ entryDesc :: c
entryDesc = a -> c
mkDesc a
val,
entryWeight :: Int
entryWeight = Int
1,
entryValue :: a
entryValue = a
val,
entryDeleted :: Bool
entryDeleted = Bool
False
}
let entry = STRef s (EntryData s c a) -> Entry s c a
forall s c a. STRef s (EntryData s c a) -> Entry s c a
Entry STRef s (EntryData s c a)
e
m <- readSTRef mref
writeSTRef mref (Map.insert val entry m)
return entry
getClass :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m (Class s c a)
getClass :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Class s c a)
getClass Equiv s c a
eq a
v = do
en <- (Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
getEntry' Equiv s c a
eq a
v)
liftM Class $ newSTRef en
getEntry' :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m (Entry s c a)
getEntry' :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
getEntry' Equiv s c a
eq a
v = do
mentry <- Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
getEntry Equiv s c a
eq a
v
case mentry of
Maybe (Entry s c a)
Nothing -> Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
mkEntry Equiv s c a
eq a
v
Just Entry s c a
entry -> Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
entry
getEntry :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
getEntry :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
getEntry Equiv{ entries :: forall s c a. Equiv s c a -> Entries s c a
entries = Entries s c a
mref } a
val = do
a -> Map a (Entry s c a) -> Maybe (Entry s c a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
val (Map a (Entry s c a) -> Maybe (Entry s c a))
-> STT s m (Map a (Entry s c a)) -> STT s m (Maybe (Entry s c a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Entries s c a -> STT s m (Map a (Entry s c a))
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef Entries s c a
mref
equateEntry :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Entry s c a -> Entry s c a -> STT s m (Entry s c a)
equateEntry :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Entry s c a -> Entry s c a -> STT s m (Entry s c a)
equateEntry Equiv {combDesc :: forall s c a. Equiv s c a -> c -> c -> c
combDesc = c -> c -> c
mkDesc} repx :: Entry s c a
repx@(Entry STRef s (EntryData s c a)
rx) repy :: Entry s c a
repy@(Entry STRef s (EntryData s c a)
ry) =
if (STRef s (EntryData s c a)
rx STRef s (EntryData s c a) -> STRef s (EntryData s c a) -> Bool
forall a. Eq a => a -> a -> Bool
/= STRef s (EntryData s c a)
ry) then do
dx <- STRef s (EntryData s c a) -> STT s m (EntryData s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s (EntryData s c a)
rx
dy <- readSTRef ry
case (dx, dy) of
( Root{entryWeight :: forall s c a. EntryData s c a -> Int
entryWeight = Int
wx, entryDesc :: forall s c a. EntryData s c a -> c
entryDesc = c
chx, entryValue :: forall s c a. EntryData s c a -> a
entryValue = a
vx}
, Root{entryWeight :: forall s c a. EntryData s c a -> Int
entryWeight = Int
wy, entryDesc :: forall s c a. EntryData s c a -> c
entryDesc = c
chy, entryValue :: forall s c a. EntryData s c a -> a
entryValue = a
vy} ) ->
if Int
wx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
wy
then do
STRef s (EntryData s c a) -> EntryData s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (EntryData s c a)
ry Node {entryParent :: Entry s c a
entryParent = Entry s c a
repx, entryValue :: a
entryValue = a
vy}
STRef s (EntryData s c a) -> EntryData s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (EntryData s c a)
rx EntryData s c a
dx{entryWeight = wx + wy, entryDesc = mkDesc chx chy}
Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
repx
else do
STRef s (EntryData s c a) -> EntryData s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (EntryData s c a)
rx Node {entryParent :: Entry s c a
entryParent = Entry s c a
repy, entryValue :: a
entryValue = a
vx}
STRef s (EntryData s c a) -> EntryData s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (EntryData s c a)
ry EntryData s c a
dy{entryWeight = wx + wy, entryDesc = mkDesc chx chy}
Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
repy
(EntryData s c a, EntryData s c a)
_ -> [Char] -> STT s m (Entry s c a)
forall a. HasCallStack => [Char] -> a
error [Char]
"error on `equateEntry`"
else Entry s c a -> STT s m (Entry s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Entry s c a
repx
combineEntries :: (Monad m, Applicative m, Ord a)
=> Equiv s c a -> [b] -> (b -> STT s m (Entry s c a)) -> STT s m ()
combineEntries :: forall (m :: * -> *) a s c b.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [b] -> (b -> STT s m (Entry s c a)) -> STT s m ()
combineEntries Equiv s c a
_ [] b -> STT s m (Entry s c a)
_ = () -> STT s m ()
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
combineEntries Equiv s c a
eq (b
e:[b]
es) b -> STT s m (Entry s c a)
rep = do
er <- b -> STT s m (Entry s c a)
rep b
e
run er es
where run :: Entry s c a -> [b] -> STT s m ()
run Entry s c a
er (b
f:[b]
r) = do
fr <- b -> STT s m (Entry s c a)
rep b
f
er' <- equateEntry eq er fr
run er' r
run Entry s c a
_ [b]
_ = () -> STT s m ()
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
combineAll :: (Monad m, Applicative m, Ord a) => Equiv s c a -> [Class s c a] -> STT s m ()
combineAll :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [Class s c a] -> STT s m ()
combineAll Equiv s c a
eq [Class s c a]
cls = Equiv s c a
-> [Class s c a]
-> (Class s c a -> STT s m (Entry s c a))
-> STT s m ()
forall (m :: * -> *) a s c b.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [b] -> (b -> STT s m (Entry s c a)) -> STT s m ()
combineEntries Equiv s c a
eq [Class s c a]
cls (Equiv s c a -> Class s c a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m (Entry s c a)
classRep Equiv s c a
eq)
combine :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Class s c a -> Class s c a -> STT s m (Class s c a)
combine :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> Class s c a -> STT s m (Class s c a)
combine Equiv s c a
eq Class s c a
x Class s c a
y = Equiv s c a -> [Class s c a] -> STT s m ()
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [Class s c a] -> STT s m ()
combineAll Equiv s c a
eq [Class s c a
x,Class s c a
y] STT s m () -> STT s m (Class s c a) -> STT s m (Class s c a)
forall a b. STT s m a -> STT s m b -> STT s m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Class s c a -> STT s m (Class s c a)
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Class s c a
x
equateAll :: (Monad m, Applicative m, Ord a) => Equiv s c a -> [a] -> STT s m ()
equateAll :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [a] -> STT s m ()
equateAll Equiv s c a
eq [a]
cls = Equiv s c a -> [a] -> (a -> STT s m (Entry s c a)) -> STT s m ()
forall (m :: * -> *) a s c b.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [b] -> (b -> STT s m (Entry s c a)) -> STT s m ()
combineEntries Equiv s c a
eq [a]
cls (Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
representative Equiv s c a
eq)
equate :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> a -> STT s m ()
equate :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> a -> STT s m ()
equate Equiv s c a
eq a
x a
y = Equiv s c a -> [a] -> STT s m ()
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> [a] -> STT s m ()
equateAll Equiv s c a
eq [a
x,a
y]
desc :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Class s c a -> STT s m c
desc :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m c
desc Equiv s c a
eq Class s c a
cl = do
Entry e <- Equiv s c a -> Class s c a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m (Entry s c a)
classRep Equiv s c a
eq Class s c a
cl
liftM entryDesc $ readSTRef e
classDesc :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m c
classDesc :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m c
classDesc Equiv s c a
eq a
val = do
Entry e <- Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
representative Equiv s c a
eq a
val
liftM entryDesc $ readSTRef e
same :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Class s c a -> Class s c a -> STT s m Bool
same :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> Class s c a -> STT s m Bool
same Equiv s c a
eq Class s c a
c1 Class s c a
c2 = do
(Entry r1) <- Equiv s c a -> Class s c a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m (Entry s c a)
classRep Equiv s c a
eq Class s c a
c1
(Entry r2) <- classRep eq c2
return (r1 == r2)
equivalent :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> a -> STT s m Bool
equivalent :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> a -> STT s m Bool
equivalent Equiv s c a
eq a
v1 a
v2 = do
(Entry r1) <- Equiv s c a -> a -> STT s m (Entry s c a)
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Entry s c a)
representative Equiv s c a
eq a
v1
(Entry r2) <- representative eq v2
return (r1 == r2)
modifySTRef :: (Monad m, Applicative m) => STRef s a -> (a -> a) -> STT s m ()
modifySTRef :: forall (m :: * -> *) s a.
(Monad m, Applicative m) =>
STRef s a -> (a -> a) -> STT s m ()
modifySTRef STRef s a
r a -> a
f = STRef s a -> STT s m a
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s a
r STT s m a -> (a -> STT s m ()) -> STT s m ()
forall a b. STT s m a -> (a -> STT s m b) -> STT s m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (STRef s a -> a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s a
r (a -> STT s m ()) -> (a -> a) -> a -> STT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f)
removeEntry :: (Monad m, Applicative m, Ord a) => Entry s c a -> STT s m ()
removeEntry :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Entry s c a -> STT s m ()
removeEntry (Entry STRef s (EntryData s c a)
r) = STRef s (EntryData s c a)
-> (EntryData s c a -> EntryData s c a) -> STT s m ()
forall (m :: * -> *) s a.
(Monad m, Applicative m) =>
STRef s a -> (a -> a) -> STT s m ()
modifySTRef STRef s (EntryData s c a)
r EntryData s c a -> EntryData s c a
forall {s} {c} {a} {s}. EntryData s c a -> EntryData s c a
change
where change :: EntryData s c a -> EntryData s c a
change EntryData s c a
e = EntryData s c a
e {entryDeleted = True}
remove :: (Monad m, Applicative m, Ord a) => Equiv s c a -> Class s c a -> STT s m Bool
remove :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> Class s c a -> STT s m Bool
remove Equiv s c a
eq (Class STRef s (Entry s c a)
p) = do
entry <- STRef s (Entry s c a) -> STT s m (Entry s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef STRef s (Entry s c a)
p
(mrepr,del) <- representative' entry
if del then do
v <- liftM entryValue $ readSTRef (unentry entry)
men <- getEntry eq v
case men of
Maybe (Entry s c a)
Nothing -> Bool -> STT s m Bool
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Just Entry s c a
en -> do
STRef s (Entry s c a) -> Entry s c a -> STT s m ()
forall (m :: * -> *) s a.
Applicative m =>
STRef s a -> a -> STT s m ()
writeSTRef STRef s (Entry s c a)
p Entry s c a
en
(mentry,del) <- Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
forall (m :: * -> *) s c a.
(Monad m, Applicative m) =>
Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
representative' Entry s c a
en
if del
then return False
else removeEntry (fromMaybe en mentry)
>> return True
else removeEntry (fromMaybe entry mrepr)
>> return True
removeClass :: (Monad m, Applicative m, Ord a) => Equiv s c a -> a -> STT s m Bool
removeClass :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m Bool
removeClass Equiv s c a
eq a
v = do
mentry <- Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> a -> STT s m (Maybe (Entry s c a))
getEntry Equiv s c a
eq a
v
case mentry of
Maybe (Entry s c a)
Nothing -> Bool -> STT s m Bool
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Just Entry s c a
entry -> do
(mentry, del) <- Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
forall (m :: * -> *) s c a.
(Monad m, Applicative m) =>
Entry s c a -> STT s m (Maybe (Entry s c a), Bool)
representative' Entry s c a
entry
if del
then return False
else removeEntry (fromMaybe entry mentry)
>> return True
values :: (Monad m, Applicative m, Ord a) => Equiv s c a -> STT s m [a]
values :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> STT s m [a]
values Equiv {entries :: forall s c a. Equiv s c a -> Entries s c a
entries = Entries s c a
mref} = Map a (Entry s c a) -> [a]
forall k a. Map k a -> [k]
Map.keys (Map a (Entry s c a) -> [a])
-> STT s m (Map a (Entry s c a)) -> STT s m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Entries s c a -> STT s m (Map a (Entry s c a))
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef Entries s c a
mref
classes :: (Monad m, Applicative m, Ord a) => Equiv s c a -> STT s m [Class s c a]
classes :: forall (m :: * -> *) a s c.
(Monad m, Applicative m, Ord a) =>
Equiv s c a -> STT s m [Class s c a]
classes Equiv {entries :: forall s c a. Equiv s c a -> Entries s c a
entries = Entries s c a
mref} = do
allEntries <- Map a (Entry s c a) -> [Entry s c a]
forall k a. Map k a -> [a]
Map.elems (Map a (Entry s c a) -> [Entry s c a])
-> STT s m (Map a (Entry s c a)) -> STT s m [Entry s c a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Entries s c a -> STT s m (Map a (Entry s c a))
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef Entries s c a
mref
rootEntries <- filterM isRoot allEntries
mapM (fmap Class . newSTRef) $ rootEntries
where
isRoot :: Entry s c a -> STT s m Bool
isRoot Entry s c a
e = do
x <- STRef s (EntryData s c a) -> STT s m (EntryData s c a)
forall (m :: * -> *) s a. Applicative m => STRef s a -> STT s m a
readSTRef (Entry s c a -> STRef s (EntryData s c a)
forall s c a. Entry s c a -> STRef s (EntryData s c a)
unentry Entry s c a
e)
case x of
Node {} -> Bool -> STT s m Bool
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Root {} -> Bool -> STT s m Bool
forall a. a -> STT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True