module Language.Lexer.Tlex.Data.NonEmptyEnumStringSet (
    NonEmptyEnumStringSet (..),
    empty,
    insert,
    insertSingleByte,
    singleton,
    union,
    intersection,
    fromList,
) where

import           Prelude

import qualified Data.EnumMap.Strict as EnumMap
import qualified Data.EnumSet        as EnumSet
import qualified Data.List.NonEmpty  as NonEmpty


data NonEmptyEnumStringSet a = NonEmptyEnumStringSet
    { NonEmptyEnumStringSet a -> EnumSet a
singleEnums :: EnumSet.EnumSet a
    , NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings :: EnumMap.EnumMap a (NonEmptyEnumStringSet a)
    }
    deriving (NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
(NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool)
-> (NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool)
-> Eq (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
$c/= :: forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
== :: NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
$c== :: forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
Eq, Int -> NonEmptyEnumStringSet a -> ShowS
[NonEmptyEnumStringSet a] -> ShowS
NonEmptyEnumStringSet a -> String
(Int -> NonEmptyEnumStringSet a -> ShowS)
-> (NonEmptyEnumStringSet a -> String)
-> ([NonEmptyEnumStringSet a] -> ShowS)
-> Show (NonEmptyEnumStringSet a)
forall a.
(Enum a, Show a) =>
Int -> NonEmptyEnumStringSet a -> ShowS
forall a. (Enum a, Show a) => [NonEmptyEnumStringSet a] -> ShowS
forall a. (Enum a, Show a) => NonEmptyEnumStringSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NonEmptyEnumStringSet a] -> ShowS
$cshowList :: forall a. (Enum a, Show a) => [NonEmptyEnumStringSet a] -> ShowS
show :: NonEmptyEnumStringSet a -> String
$cshow :: forall a. (Enum a, Show a) => NonEmptyEnumStringSet a -> String
showsPrec :: Int -> NonEmptyEnumStringSet a -> ShowS
$cshowsPrec :: forall a.
(Enum a, Show a) =>
Int -> NonEmptyEnumStringSet a -> ShowS
Show)

empty :: Enum a => NonEmptyEnumStringSet a
empty :: NonEmptyEnumStringSet a
empty = NonEmptyEnumStringSet :: forall a.
EnumSet a
-> EnumMap a (NonEmptyEnumStringSet a) -> NonEmptyEnumStringSet a
NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = EnumSet a
forall k. EnumSet k
EnumSet.empty
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = EnumMap a (NonEmptyEnumStringSet a)
forall k a. EnumMap k a
EnumMap.empty
    }

singleton :: Enum a => NonEmpty.NonEmpty a -> NonEmptyEnumStringSet a
singleton :: NonEmpty a -> NonEmptyEnumStringSet a
singleton (a
x NonEmpty.:| [a]
xs) = case [a]
xs of
    [] -> NonEmptyEnumStringSet :: forall a.
EnumSet a
-> EnumMap a (NonEmptyEnumStringSet a) -> NonEmptyEnumStringSet a
NonEmptyEnumStringSet
        { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = a -> EnumSet a
forall k. Enum k => k -> EnumSet k
EnumSet.singleton a
x
        , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = EnumMap a (NonEmptyEnumStringSet a)
forall k a. EnumMap k a
EnumMap.empty
        }
    a
y:[a]
ys -> NonEmptyEnumStringSet :: forall a.
EnumSet a
-> EnumMap a (NonEmptyEnumStringSet a) -> NonEmptyEnumStringSet a
NonEmptyEnumStringSet
        { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = EnumSet a
forall k. EnumSet k
EnumSet.empty
        , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = a -> NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall k a. Enum k => k -> a -> EnumMap k a
EnumMap.singleton a
x do
            NonEmpty a -> NonEmptyEnumStringSet a
forall a. Enum a => NonEmpty a -> NonEmptyEnumStringSet a
singleton do a
y a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
NonEmpty.:| [a]
ys
        }

insert :: Enum a
    => NonEmpty.NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert :: NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert (a
x NonEmpty.:| [a]
xs) NonEmptyEnumStringSet a
s = case [a]
xs of
    [] -> a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
forall a.
Enum a =>
a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte a
x NonEmptyEnumStringSet a
s
    a
y:[a]
ys -> let xs' :: NonEmpty a
xs' = a
y a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
NonEmpty.:| [a]
ys in NonEmptyEnumStringSet a
s
        { $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = (Maybe (NonEmptyEnumStringSet a)
 -> Maybe (NonEmptyEnumStringSet a))
-> a
-> EnumMap a (NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
forall k a.
Enum k =>
(Maybe a -> Maybe a) -> k -> EnumMap k a -> EnumMap k a
EnumMap.alter
            do \case
                Maybe (NonEmptyEnumStringSet a)
Nothing  -> NonEmptyEnumStringSet a -> Maybe (NonEmptyEnumStringSet a)
forall a. a -> Maybe a
Just do NonEmpty a -> NonEmptyEnumStringSet a
forall a. Enum a => NonEmpty a -> NonEmptyEnumStringSet a
singleton NonEmpty a
xs'
                Just NonEmptyEnumStringSet a
xss -> NonEmptyEnumStringSet a -> Maybe (NonEmptyEnumStringSet a)
forall a. a -> Maybe a
Just do NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
forall a.
Enum a =>
NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert NonEmpty a
xs' NonEmptyEnumStringSet a
xss
            do a
x
            do NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s
        }

insertSingleByte :: Enum a => a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte :: a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte a
x NonEmptyEnumStringSet a
s = NonEmptyEnumStringSet a
s
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = a -> EnumSet a -> EnumSet a
forall k. Enum k => k -> EnumSet k -> EnumSet k
EnumSet.insert a
x
        do NonEmptyEnumStringSet a -> EnumSet a
forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s
    }

union :: Enum a
    => NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
union :: NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
union NonEmptyEnumStringSet a
s1 NonEmptyEnumStringSet a
s2 = NonEmptyEnumStringSet :: forall a.
EnumSet a
-> EnumMap a (NonEmptyEnumStringSet a) -> NonEmptyEnumStringSet a
NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = NonEmptyEnumStringSet a -> EnumSet a
forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s1 EnumSet a -> EnumSet a -> EnumSet a
forall k. EnumSet k -> EnumSet k -> EnumSet k
`EnumSet.union` NonEmptyEnumStringSet a -> EnumSet a
forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s2
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = (NonEmptyEnumStringSet a
 -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
forall k a.
(a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
EnumMap.unionWith
        do \NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
xs2 -> NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
`union` NonEmptyEnumStringSet a
xs2
        do NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s1
        do NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s2
    }

intersection :: Enum a
    => NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
intersection :: NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
intersection NonEmptyEnumStringSet a
s1 NonEmptyEnumStringSet a
s2 = NonEmptyEnumStringSet :: forall a.
EnumSet a
-> EnumMap a (NonEmptyEnumStringSet a) -> NonEmptyEnumStringSet a
NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = NonEmptyEnumStringSet a -> EnumSet a
forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s1 EnumSet a -> EnumSet a -> EnumSet a
forall k. EnumSet k -> EnumSet k -> EnumSet k
`EnumSet.intersection` NonEmptyEnumStringSet a -> EnumSet a
forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s2
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = (NonEmptyEnumStringSet a
 -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
-> EnumMap a (NonEmptyEnumStringSet a)
forall k a b c.
(a -> b -> c) -> EnumMap k a -> EnumMap k b -> EnumMap k c
EnumMap.intersectionWith
        do \NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
xs2 -> NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
`union` NonEmptyEnumStringSet a
xs2
        do NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s1
        do NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s2
    }

fromList :: Enum a => [NonEmpty.NonEmpty a] -> NonEmptyEnumStringSet a
fromList :: [NonEmpty a] -> NonEmptyEnumStringSet a
fromList [NonEmpty a]
xs = (NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a)
-> NonEmptyEnumStringSet a
-> [NonEmpty a]
-> NonEmptyEnumStringSet a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
forall a.
Enum a =>
NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert NonEmptyEnumStringSet a
forall a. Enum a => NonEmptyEnumStringSet a
empty [NonEmpty a]
xs