{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
module Data.EnumSet
(
EnumSet,
empty,
singleton,
fromList,
fromAscList,
fromDistinctAscList,
insert,
delete,
member,
notMember,
lookupLT,
lookupGT,
lookupLE,
lookupGE,
null,
size,
isSubsetOf,
isProperSubsetOf,
disjoint,
union,
unions,
difference,
(\\),
intersection,
filter,
partition,
split,
splitMember,
splitRoot,
map,
foldr,
foldl,
foldr',
foldl',
fold,
findMin,
findMax,
deleteMin,
deleteMax,
deleteFindMin,
deleteFindMax,
maxView,
minView,
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 #-}