    {-# LANGUAGE RecordWildCards #-}
    module Network.Wai.Middleware.Push.Referer.Multi where

    import Data.Set (Set)
    import qualified Data.Set as Set

    data Multi a = Multi {
        forall a. Multi a -> Int
    limit :: Int
      , forall a. Multi a -> [a]
    list  :: [a]
      , forall a. Multi a -> Set a
    check :: Set a
      } deriving (Multi a -> Multi a -> Bool
    (Multi a -> Multi a -> Bool)
    -> (Multi a -> Multi a -> Bool) -> Eq (Multi a)
    forall a. Eq a => Multi a -> Multi a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Multi a -> Multi a -> Bool
    == :: Multi a -> Multi a -> Bool
    $c/= :: forall a. Eq a => Multi a -> Multi a -> Bool
    /= :: Multi a -> Multi a -> Bool
    Eq, Int -> Multi a -> ShowS
    [Multi a] -> ShowS
    Multi a -> String
    (Int -> Multi a -> ShowS)
    -> (Multi a -> String) -> ([Multi a] -> ShowS) -> Show (Multi a)
    forall a. Show a => Int -> Multi a -> ShowS
    forall a. Show a => [Multi a] -> ShowS
    forall a. Show a => Multi a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Multi a -> ShowS
    showsPrec :: Int -> Multi a -> ShowS
    $cshow :: forall a. Show a => Multi a -> String
    show :: Multi a -> String
    $cshowList :: forall a. Show a => [Multi a] -> ShowS
    showList :: [Multi a] -> ShowS
    Show)

    empty :: Int -> Multi a
    empty :: forall a. Int -> Multi a
    empty Int
    n = Int -> [a] -> Set a -> Multi a
    forall a. Int -> [a] -> Set a -> Multi a
    Multi Int
    n [] Set a
    forall a. Set a
    Set.empty

    singleton :: Int -> a -> Multi a
    singleton :: forall a. Int -> a -> Multi a
    singleton Int
    n a
    v = Int -> [a] -> Set a -> Multi a
    forall a. Int -> [a] -> Set a -> Multi a
    Multi Int
    n [a
    v] (Set a -> Multi a) -> Set a -> Multi a
    forall a b. (a -> b) -> a -> b
    $ a -> Set a
    forall a. a -> Set a
    Set.singleton a
    v

    insert :: Ord a => a -> Multi a -> Multi a
    insert :: forall a. Ord a => a -> Multi a -> Multi a
    insert a
    _ m :: Multi a
    m@Multi{Int
    [a]
    Set a
    limit :: forall a. Multi a -> Int
    list :: forall a. Multi a -> [a]
    check :: forall a. Multi a -> Set a
    limit :: Int
    list :: [a]
    check :: Set a
    ..}
      | Set a -> Int
    forall a. Set a -> Int
    Set.size Set a
    check Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    limit           = Multi a
    m
    insert a
    v m :: Multi a
    m@Multi{Int
    [a]
    Set a
    limit :: forall a. Multi a -> Int
    list :: forall a. Multi a -> [a]
    check :: forall a. Multi a -> Set a
    limit :: Int
    list :: [a]
    check :: Set a
    ..}
      | Set a -> Int
    forall a. Set a -> Int
    Set.size Set a
    check Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> Int
    forall a. Set a -> Int
    Set.size Set a
    check' = Multi a
    m
      | Bool
    otherwise                         = Int -> [a] -> Set a -> Multi a
    forall a. Int -> [a] -> Set a -> Multi a
    Multi Int
    limit (a
    va -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    list) Set a
    check'
      where
        check' :: Set a
    check' = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    Set.insert a
    v Set a
    check