-- | A tiny wrapper around 'IntSet.IntSet' for representing sets of 'Enum'
-- things.
module GHC.Data.EnumSet
    ( EnumSet
    , member
    , insert
    , delete
    , toList
    , fromList
    , empty
    , difference
    ) where

import GHC.Prelude

import qualified Data.IntSet as IntSet

newtype EnumSet a = EnumSet IntSet.IntSet

member :: Enum a => a -> EnumSet a -> Bool
member :: forall a. Enum a => a -> EnumSet a -> Bool
member a
x (EnumSet IntSet
s) = Key -> IntSet -> Bool
IntSet.member (a -> Key
forall a. Enum a => a -> Key
fromEnum a
x) IntSet
s

insert :: Enum a => a -> EnumSet a -> EnumSet a
insert :: forall a. Enum a => a -> EnumSet a -> EnumSet a
insert a
x (EnumSet IntSet
s) = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet (IntSet -> EnumSet a) -> IntSet -> EnumSet a
forall a b. (a -> b) -> a -> b
$ Key -> IntSet -> IntSet
IntSet.insert (a -> Key
forall a. Enum a => a -> Key
fromEnum a
x) IntSet
s

delete :: Enum a => a -> EnumSet a -> EnumSet a
delete :: forall a. Enum a => a -> EnumSet a -> EnumSet a
delete a
x (EnumSet IntSet
s) = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet (IntSet -> EnumSet a) -> IntSet -> EnumSet a
forall a b. (a -> b) -> a -> b
$ Key -> IntSet -> IntSet
IntSet.delete (a -> Key
forall a. Enum a => a -> Key
fromEnum a
x) IntSet
s

toList :: Enum a => EnumSet a -> [a]
toList :: forall a. Enum a => EnumSet a -> [a]
toList (EnumSet IntSet
s) = (Key -> a) -> [Key] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Key -> a
forall a. Enum a => Key -> a
toEnum ([Key] -> [a]) -> [Key] -> [a]
forall a b. (a -> b) -> a -> b
$ IntSet -> [Key]
IntSet.toList IntSet
s

fromList :: Enum a => [a] -> EnumSet a
fromList :: forall a. Enum a => [a] -> EnumSet a
fromList = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet (IntSet -> EnumSet a) -> ([a] -> IntSet) -> [a] -> EnumSet a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Key] -> IntSet
IntSet.fromList ([Key] -> IntSet) -> ([a] -> [Key]) -> [a] -> IntSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Key) -> [a] -> [Key]
forall a b. (a -> b) -> [a] -> [b]
map a -> Key
forall a. Enum a => a -> Key
fromEnum

empty :: EnumSet a
empty :: forall a. EnumSet a
empty = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet IntSet
IntSet.empty

difference :: EnumSet a -> EnumSet a -> EnumSet a
difference :: forall a. EnumSet a -> EnumSet a -> EnumSet a
difference (EnumSet IntSet
a) (EnumSet IntSet
b) = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet (IntSet -> IntSet -> IntSet
IntSet.difference IntSet
a IntSet
b)