module Data.LinkedHashSet
(
LinkedHashSet
, empty
, singleton
, union
, unions
, null
, size
, member
, insert
, delete
, map
, difference
, intersection
, foldl'
, foldr
, filter
, toList
, fromList
) where
import Prelude hiding (null, lookup, map, foldr, filter)
import Control.DeepSeq (NFData(rnf))
import Data.Hashable (Hashable)
import qualified Data.List as L
import qualified Data.LinkedHashMap.Seq as M
newtype LinkedHashSet a = LinkedHashSet {
asMap :: M.LinkedHashMap a ()
}
instance (Show a) => Show (LinkedHashSet a) where
showsPrec d m = showParen (d > 10) $
showString "fromList " . shows (toList m)
empty :: LinkedHashSet a
empty = LinkedHashSet M.empty
singleton :: (Eq a, Hashable a) => a -> LinkedHashSet a
singleton a = LinkedHashSet (M.singleton a ())
union :: (Eq a, Hashable a) => LinkedHashSet a -> LinkedHashSet a -> LinkedHashSet a
union s1 s2 = LinkedHashSet $ M.union (asMap s1) (asMap s2)
unions :: (Eq a, Hashable a) => [LinkedHashSet a] -> LinkedHashSet a
unions = L.foldl' union empty
null :: LinkedHashSet a -> Bool
null = M.null . asMap
size :: LinkedHashSet a -> Int
size = M.size . asMap
member :: (Eq a, Hashable a) => a -> LinkedHashSet a -> Bool
member a s = case M.lookup a (asMap s) of
Just _ -> True
_ -> False
insert :: (Eq a, Hashable a) => a -> LinkedHashSet a -> LinkedHashSet a
insert a = LinkedHashSet . M.insert a () . asMap
delete :: (Eq a, Hashable a) => a -> LinkedHashSet a -> LinkedHashSet a
delete a = LinkedHashSet . M.delete a . asMap
map :: (Hashable b, Eq b) => (a -> b) -> LinkedHashSet a -> LinkedHashSet b
map f = fromList . L.map f . toList
difference :: (Eq a, Hashable a) => LinkedHashSet a -> LinkedHashSet a -> LinkedHashSet a
difference (LinkedHashSet a) (LinkedHashSet b) = LinkedHashSet (M.difference a b)
intersection :: (Eq a, Hashable a) => LinkedHashSet a -> LinkedHashSet a -> LinkedHashSet a
intersection (LinkedHashSet a) (LinkedHashSet b) = LinkedHashSet (M.intersection a b)
foldl' :: (a -> b -> a) -> a -> LinkedHashSet b -> a
foldl' f z0 = M.foldlWithKey' g z0 . asMap
where g z k _ = f z k
foldr :: (b -> a -> a) -> a -> LinkedHashSet b -> a
foldr f z0 = M.foldrWithKey g z0 . asMap
where g k _ z = f k z
filter :: (Eq a, Hashable a) => (a -> Bool) -> LinkedHashSet a -> LinkedHashSet a
filter p = LinkedHashSet . M.filterWithKey q . asMap
where q k _ = p k
toList :: LinkedHashSet a -> [a]
toList t = L.map (\(k, _) -> k) $ M.toList (asMap t)
fromList :: (Eq a, Hashable a) => [a] -> LinkedHashSet a
fromList as = LinkedHashSet $ M.fromList $ zip as $ cycle [()]
instance (NFData a) => NFData (LinkedHashSet a) where
rnf = rnf . asMap