{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE ViewPatterns #-} -- | -- Module : Data.EnumSet -- Description : Data.IntSet, wrapped with Enum module Data.EnumSet ( -- * Set type EnumSet, -- * Construction empty, singleton, fromList, fromAscList, fromDistinctAscList, -- * Insertion insert, -- * Deletion delete, -- * Query member, notMember, lookupLT, lookupGT, lookupLE, lookupGE, null, size, isSubsetOf, isProperSubsetOf, disjoint, -- * Combine union, unions, difference, (\\), intersection, -- * Filter filter, partition, split, splitMember, splitRoot, -- * Map map, -- * Folds foldr, foldl, -- ** Strict folds foldr', foldl', -- ** Legacy folds fold, -- * Min\/Max findMin, findMax, deleteMin, deleteMax, deleteFindMin, deleteFindMax, maxView, minView, -- * Conversion -- ** List elems, toList, toAscList, toDescList, ) where import Data.Bifunctor (first) import Data.Coerce (Coercible, coerce) import Data.EnumSet.Wrapper (EnumSet (..)) import qualified Data.IntSet as IntSet import Prelude ( ($), (.), Bool, Enum, Foldable, Int, Maybe, fmap, fromEnum, toEnum, ) (\\) :: EnumSet k -> EnumSet k -> EnumSet k (\\) = coerce (IntSet.\\) {-# INLINE (\\) #-} null :: EnumSet k -> Bool null = coerce IntSet.null {-# INLINE null #-} size :: EnumSet k -> Int size = coerce IntSet.size {-# INLINE size #-} member :: Enum k => k -> EnumSet k -> Bool member (fromEnum -> k) = coerce $ IntSet.member k {-# INLINE member #-} notMember :: Enum k => k -> EnumSet k -> Bool notMember (fromEnum -> k) = coerce $ IntSet.notMember k {-# INLINE notMember #-} lookupLT :: Enum k => k -> EnumSet k -> Maybe k lookupLT (fromEnum -> k) = fmap toEnum . coerce (IntSet.lookupLT k) {-# INLINE lookupLT #-} lookupGT :: Enum k => k -> EnumSet k -> Maybe k lookupGT (fromEnum -> k) = fmap toEnum . coerce (IntSet.lookupGT k) {-# INLINE lookupGT #-} lookupLE :: Enum k => k -> EnumSet k -> Maybe k lookupLE (fromEnum -> k) = fmap toEnum . coerce (IntSet.lookupLE k) {-# INLINE lookupLE #-} lookupGE :: Enum k => k -> EnumSet k -> Maybe k lookupGE (fromEnum -> k) = fmap toEnum . coerce (IntSet.lookupGE k) {-# INLINE lookupGE #-} empty :: EnumSet k empty = coerce IntSet.empty {-# INLINE empty #-} singleton :: Enum k => k -> EnumSet k singleton (fromEnum -> k) = coerce $ IntSet.singleton k {-# INLINE singleton #-} insert :: Enum k => k -> EnumSet k -> EnumSet k insert (fromEnum -> k) = coerce $ IntSet.insert k {-# INLINE insert #-} delete :: Enum k => k -> EnumSet k -> EnumSet k delete (fromEnum -> k) = coerce $ IntSet.delete k {-# INLINE delete #-} unions :: forall f k. (Foldable f, Coercible (f IntSet.IntSet) (f (EnumSet k))) => f (EnumSet k) -> EnumSet k unions = coerce $ IntSet.unions @f {-# INLINE unions #-} union :: EnumSet k -> EnumSet k -> EnumSet k union = coerce $ IntSet.union {-# INLINE union #-} difference :: EnumSet k -> EnumSet k -> EnumSet k difference = coerce $ IntSet.difference {-# INLINE difference #-} intersection :: EnumSet k -> EnumSet k -> EnumSet k intersection = coerce $ IntSet.intersection {-# INLINE intersection #-} isProperSubsetOf :: EnumSet k -> EnumSet k -> Bool isProperSubsetOf = coerce $ IntSet.isProperSubsetOf {-# INLINE isProperSubsetOf #-} isSubsetOf :: EnumSet k -> EnumSet k -> Bool isSubsetOf = coerce $ IntSet.isSubsetOf {-# INLINE isSubsetOf #-} disjoint :: EnumSet k -> EnumSet k -> Bool disjoint = coerce $ IntSet.disjoint {-# INLINE disjoint #-} filter :: Enum k => (k -> Bool) -> EnumSet k -> EnumSet k filter ((. toEnum) -> p) = coerce $ IntSet.filter p {-# INLINE filter #-} partition :: Enum k => (k -> Bool) -> EnumSet k -> (EnumSet k, EnumSet k) partition ((. toEnum) -> p) = coerce $ IntSet.partition p {-# INLINE partition #-} split :: Enum k => k -> EnumSet k -> (EnumSet k, EnumSet k) split (fromEnum -> k) = coerce $ IntSet.split k {-# INLINE split #-} splitMember :: Enum k => k -> EnumSet k -> (EnumSet k, Bool, EnumSet k) splitMember (fromEnum -> k) = coerce $ IntSet.splitMember k {-# INLINE splitMember #-} maxView :: Enum k => EnumSet k -> Maybe (k, EnumSet k) maxView = fmap (first toEnum) . coerce IntSet.maxView {-# INLINE maxView #-} minView :: Enum k => EnumSet k -> Maybe (k, EnumSet k) minView = fmap (first toEnum) . coerce IntSet.minView {-# INLINE minView #-} deleteFindMin :: Enum k => EnumSet k -> (k, EnumSet k) deleteFindMin = first toEnum . coerce IntSet.deleteFindMin {-# INLINE deleteFindMin #-} deleteFindMax :: Enum k => EnumSet k -> (k, EnumSet k) deleteFindMax = first toEnum . coerce IntSet.deleteFindMax {-# INLINE deleteFindMax #-} findMin :: Enum k => EnumSet k -> k findMin = toEnum . coerce IntSet.findMin {-# INLINE findMin #-} findMax :: Enum k => EnumSet k -> k findMax = toEnum . coerce IntSet.findMax {-# INLINE findMax #-} deleteMin :: EnumSet k -> EnumSet k deleteMin = coerce IntSet.deleteMin {-# INLINE deleteMin #-} deleteMax :: Enum k => EnumSet k -> EnumSet k deleteMax = coerce IntSet.deleteMax {-# INLINE deleteMax #-} map :: Enum k => (k -> k) -> EnumSet k -> EnumSet k map ((. toEnum) . (fromEnum .) -> f)= coerce $ IntSet.map f {-# INLINE map #-} fold :: Enum k => (k -> b -> b) -> b -> EnumSet k -> b fold ((. toEnum) -> f) = coerce $ IntSet.fold f {-# INLINE fold #-} foldr :: Enum k => (k -> b -> b) -> b -> EnumSet k -> b foldr ((. toEnum) -> f) = coerce $ IntSet.foldr f {-# INLINE foldr #-} foldr' :: Enum k => (k -> b -> b) -> b -> EnumSet k -> b foldr' ((. toEnum) -> f) = coerce $ IntSet.foldr' f {-# INLINE foldr' #-} foldl :: Enum k => (a -> k -> a) -> a -> EnumSet k -> a foldl (fmap (. toEnum) -> f) = coerce $ IntSet.foldl f {-# INLINE foldl #-} foldl' :: Enum k => (a -> k -> a) -> a -> EnumSet k -> a foldl' (fmap (. toEnum) -> f) = coerce $ IntSet.foldl' f {-# INLINE foldl' #-} elems :: Enum k => EnumSet k -> [k] elems = fmap toEnum . coerce (IntSet.elems) {-# INLINE elems #-} toList :: Enum k => EnumSet k -> [k] toList = fmap toEnum . coerce (IntSet.toList) {-# INLINE toList #-} toAscList :: Enum k => EnumSet k -> [k] toAscList = fmap toEnum . coerce (IntSet.toAscList) {-# INLINE toAscList #-} toDescList :: Enum k => EnumSet k -> [k] toDescList = fmap toEnum . coerce (IntSet.toDescList) {-# INLINE toDescList #-} fromList :: Enum k => [k] -> EnumSet k fromList (fmap fromEnum -> xs) = coerce $ IntSet.fromList xs {-# INLINE fromList #-} fromAscList :: Enum k => [k] -> EnumSet k fromAscList (fmap fromEnum -> xs) = coerce $ IntSet.fromAscList xs {-# INLINE fromAscList #-} fromDistinctAscList :: Enum k => [k] -> EnumSet k fromDistinctAscList (fmap fromEnum -> xs) = coerce $ IntSet.fromDistinctAscList xs {-# INLINE fromDistinctAscList #-} splitRoot :: EnumSet k -> [EnumSet k] splitRoot = coerce $ IntSet.splitRoot {-# INLINE splitRoot #-}