module STMContainers.Set
(
Set,
Element,
new,
newIO,
insert,
delete,
deleteAll,
lookup,
focus,
null,
size,
stream,
)
where
import STMContainers.Prelude hiding (insert, delete, lookup, alter, foldM, toList, empty, null)
import qualified STMContainers.HAMT as HAMT
import qualified STMContainers.HAMT.Nodes as HAMTNodes
import qualified Focus
newtype Set e = Set {hamt :: HAMT.HAMT (HAMTElement e)}
deriving (Typeable)
type Element a = (Eq a, Hashable a)
newtype HAMTElement e = HAMTElement e
instance (Eq e) => HAMTNodes.Element (HAMTElement e) where
type ElementKey (HAMTElement e) = e
elementKey (HAMTElement e) = e
elementValue :: HAMTElement e -> e
elementValue (HAMTElement e) = e
insert :: (Element e) => e -> Set e -> STM ()
insert e = HAMT.insert (HAMTElement e) . hamt
delete :: (Element e) => e -> Set e -> STM ()
delete e = HAMT.focus Focus.deleteM e . hamt
deleteAll :: Set e -> STM ()
deleteAll = HAMT.deleteAll . hamt
lookup :: (Element e) => e -> Set e -> STM Bool
lookup e = fmap (maybe False (const True)) . HAMT.focus Focus.lookupM e . hamt
focus :: (Element e) => Focus.StrategyM STM () r -> e -> Set e -> STM r
focus s e = HAMT.focus elementStrategy e . hamt
where
elementStrategy =
(fmap . fmap . fmap) (const (HAMTElement e)) . s . fmap (const ())
new :: STM (Set e)
new = Set <$> HAMT.new
newIO :: IO (Set e)
newIO = Set <$> HAMT.newIO
null :: Set e -> STM Bool
null = HAMT.null . hamt
size :: Set e -> STM Int
size (Set h) = HAMTNodes.size h
stream :: Set e -> ListT STM e
stream = fmap elementValue . HAMT.stream . hamt