{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : Data.HKeySet -- Copyright : (c) Atze van der Ploeg 2013 -- License : BSD-style -- Maintainer : atzeus@gmail.org -- Stability : provisional -- Portability : portable -- -- A set of 'HKey's module Data.HKeySet ( HKeySet -- * Construction , empty , singleton -- * Combine , union , unions -- * Basic interface , null , size , member , insert , delete -- * Difference and intersection , difference , intersection -- * KeySet-HMap functions , overlap , sameKeys , removeKeys ) where import Data.Unique import Data.HKey import Data.HMap(HMap) import qualified Data.HMap as S import qualified Data.List as List import Prelude hiding (null) -- | The type of hetrogenous key sets. newtype HKeySet = HKeySet HMap -- | /O(1)/ Construct an empty key set. empty :: HKeySet empty = HKeySet S.empty -- | /O(1)/ Construct a set with a single element. singleton :: HKey s a -> HKeySet singleton x = HKeySet (S.singleton x undefined) #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE singleton #-} #endif -- | /O(n+m)/ Construct a key set containing all elements from both sets. -- -- To obtain good performance, the smaller set must be presented as -- the first argument. union :: HKeySet -> HKeySet -> HKeySet union (HKeySet s1) (HKeySet s2) = HKeySet (s1 `S.union` s2) {-# INLINE union #-} -- | Construct a key set containing all elements from a list of key sets. unions = List.foldl' union empty {-# INLINE unions #-} -- | /O(1)/ Return 'True' if this key set is empty, 'False' otherwise. null :: HKeySet -> Bool null (HKeySet x) = S.null x {-# INLINE null #-} -- | /O(n)/ Return the number of elements in this set. size :: HKeySet -> Int size (HKeySet x) = S.size x {-# INLINE size #-} -- | /O(min(n,W))/ Return 'True' if the given value is present in this -- set, 'False' otherwise. member :: HKey s a -> HKeySet -> Bool member x (HKeySet s) = x `S.member` s #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE member #-} #endif -- | /O(min(n,W))/ Add the specified value to this set. insert :: HKey x a -> HKeySet -> HKeySet insert x (HKeySet s) = HKeySet (S.insert x undefined s) #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE insert #-} #endif -- | /O(min(n,W))/ Remove the specified value from this set if -- present. delete :: HKey s a -> HKeySet -> HKeySet delete x (HKeySet s) = HKeySet (S.delete x s) #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE delete #-} #endif -- | /O(n)/ Difference of two sets. Return elements of the first set -- not existing in the second. difference :: HKeySet -> HKeySet -> HKeySet difference (HKeySet a) (HKeySet b) = HKeySet (S.difference a b) #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE difference #-} #endif -- | /O(n)/ Intersection of two sets. Return elements present in both -- the first set and the second. intersection :: HKeySet -> HKeySet -> HKeySet intersection (HKeySet a) (HKeySet b) = HKeySet (S.intersection a b) #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE intersection #-} #endif {-------------------------------------------------------------------- KeySet-HMap functions --------------------------------------------------------------------} -- | /O(n)/. Does the map carry any of the keys? overlap :: HMap -> HKeySet -> Bool overlap h (HKeySet s) = not $ S.null (h `S.intersection` s) -- | /O(n)/. Do the keyset and the map have the same keys? sameKeys :: HMap -> HKeySet -> Bool sameKeys h (HKeySet s) = S.null (h `S.difference` s) -- | /O(n)/. Remove the keys from the keyset from the map. removeKeys :: HMap -> HKeySet -> HMap removeKeys h (HKeySet s) = h `S.difference` s