{-# 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 k1, Enum k2) => (k1 -> k2) -> EnumSet k1 -> EnumSet k2
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 #-}