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

import GhcPrelude

import qualified Data.IntSet as IntSet

newtype EnumSet a = EnumSet IntSet.IntSet

member :: Enum a => a -> EnumSet a -> Bool
member :: 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 :: 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 :: 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 :: 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 :: [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 :: EnumSet a
empty = IntSet -> EnumSet a
forall a. IntSet -> EnumSet a
EnumSet IntSet
IntSet.empty