module Language.Lexer.Tlex.Data.Bag (
    Bag,
    fromList,
    singleton,
) where

import           Language.Lexer.Tlex.Prelude


data Bag a
    = EmptyBag
    | UnitBag a
    | IncludeBags (Bag a) (Bag a)
    | ListBag [a]
    deriving (Int -> Bag a -> ShowS
forall a. Show a => Int -> Bag a -> ShowS
forall a. Show a => [Bag a] -> ShowS
forall a. Show a => Bag a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Bag a] -> ShowS
$cshowList :: forall a. Show a => [Bag a] -> ShowS
show :: Bag a -> String
$cshow :: forall a. Show a => Bag a -> String
showsPrec :: Int -> Bag a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Bag a -> ShowS
Show, forall a b. a -> Bag b -> Bag a
forall a b. (a -> b) -> Bag a -> Bag b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Bag b -> Bag a
$c<$ :: forall a b. a -> Bag b -> Bag a
fmap :: forall a b. (a -> b) -> Bag a -> Bag b
$cfmap :: forall a b. (a -> b) -> Bag a -> Bag b
Functor)

instance Foldable Bag where
    foldr :: forall a b. (a -> b -> b) -> b -> Bag a -> b
foldr a -> b -> b
k b
z = \case
        Bag a
EmptyBag          -> b
z
        UnitBag a
x         -> a -> b -> b
k a
x b
z
        IncludeBags Bag a
b1 Bag a
b2 -> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
k (forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
k b
z Bag a
b2) Bag a
b1
        ListBag [a]
xs        -> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
k b
z [a]
xs

    foldMap :: forall m a. Monoid m => (a -> m) -> Bag a -> m
foldMap a -> m
f = \case
        Bag a
EmptyBag          -> forall a. Monoid a => a
mempty
        UnitBag a
x         -> a -> m
f a
x
        IncludeBags Bag a
b1 Bag a
b2 -> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f Bag a
b1 forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f Bag a
b2
        ListBag [a]
xs        -> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f [a]
xs

instance Eq a => Eq (Bag a) where
    Bag a
b1 == :: Bag a -> Bag a -> Bool
== Bag a
b2 = forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Bag a
b1 forall a. Eq a => a -> a -> Bool
== forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Bag a
b2

instance Semigroup (Bag a) where
    Bag a
EmptyBag <> :: Bag a -> Bag a -> Bag a
<> Bag a
b2 = Bag a
b2
    Bag a
b1 <> Bag a
EmptyBag = Bag a
b1
    Bag a
b1 <> Bag a
b2       = forall a. Bag a -> Bag a -> Bag a
IncludeBags Bag a
b1 Bag a
b2

instance Monoid (Bag a) where
    mempty :: Bag a
mempty = forall a. Bag a
EmptyBag

fromList :: [a] -> Bag a
fromList :: forall a. [a] -> Bag a
fromList [a]
xs = forall a. [a] -> Bag a
ListBag [a]
xs

singleton :: a -> Bag a
singleton :: forall a. a -> Bag a
singleton a
x = forall a. a -> Bag a
UnitBag a
x