{-# 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