{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Data.OSet.Strict (
OSet (Empty, (:<|:), (:|>:)),
null,
size,
empty,
singleton,
lookup,
member,
(!?),
fromList,
fromStrictSeq,
fromStrictSeqDuplicates,
toStrictSeq,
toSet,
fromSet,
fromFoldable,
fromFoldableDuplicates,
invariantHolds,
invariantHolds',
(|>),
(<|),
(|><),
(><|),
filter,
)
where
import Cardano.Ledger.Binary (
DecCBOR (decCBOR),
EncCBOR (encCBOR),
decodeSetLikeEnforceNoDuplicates,
encodeStrictSeq,
encodeTag,
setTag,
)
import Control.DeepSeq (NFData)
import Data.Aeson (ToJSON (toJSON))
import Data.Foldable qualified as F
import Data.Sequence.Strict qualified as SSeq
import Data.Set qualified as Set
import GHC.Exts qualified as GHC (IsList (..))
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks)
import Prelude hiding (filter, lookup, null, seq)
data OSet a = OSet
{ forall a. OSet a -> StrictSeq a
osSSeq :: !(SSeq.StrictSeq a)
, forall a. OSet a -> Set a
osSet :: !(Set.Set a)
}
deriving stock (OSet a -> OSet a -> Bool
forall a. Eq a => OSet a -> OSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OSet a -> OSet a -> Bool
$c/= :: forall a. Eq a => OSet a -> OSet a -> Bool
== :: OSet a -> OSet a -> Bool
$c== :: forall a. Eq a => OSet a -> OSet a -> Bool
Eq, OSet a -> OSet a -> Bool
OSet a -> OSet a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (OSet a)
forall a. Ord a => OSet a -> OSet a -> Bool
forall a. Ord a => OSet a -> OSet a -> Ordering
forall a. Ord a => OSet a -> OSet a -> OSet a
min :: OSet a -> OSet a -> OSet a
$cmin :: forall a. Ord a => OSet a -> OSet a -> OSet a
max :: OSet a -> OSet a -> OSet a
$cmax :: forall a. Ord a => OSet a -> OSet a -> OSet a
>= :: OSet a -> OSet a -> Bool
$c>= :: forall a. Ord a => OSet a -> OSet a -> Bool
> :: OSet a -> OSet a -> Bool
$c> :: forall a. Ord a => OSet a -> OSet a -> Bool
<= :: OSet a -> OSet a -> Bool
$c<= :: forall a. Ord a => OSet a -> OSet a -> Bool
< :: OSet a -> OSet a -> Bool
$c< :: forall a. Ord a => OSet a -> OSet a -> Bool
compare :: OSet a -> OSet a -> Ordering
$ccompare :: forall a. Ord a => OSet a -> OSet a -> Ordering
Ord, Int -> OSet a -> ShowS
forall a. Show a => Int -> OSet a -> ShowS
forall a. Show a => [OSet a] -> ShowS
forall a. Show a => OSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OSet a] -> ShowS
$cshowList :: forall a. Show a => [OSet a] -> ShowS
show :: OSet a -> String
$cshow :: forall a. Show a => OSet a -> String
showsPrec :: Int -> OSet a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> OSet a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (OSet a) x -> OSet a
forall a x. OSet a -> Rep (OSet a) x
$cto :: forall a x. Rep (OSet a) x -> OSet a
$cfrom :: forall a x. OSet a -> Rep (OSet a) x
Generic)
deriving (forall a. NoThunks a => Context -> OSet a -> IO (Maybe ThunkInfo)
forall a. NoThunks a => Proxy (OSet a) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (OSet a) -> String
$cshowTypeOf :: forall a. NoThunks a => Proxy (OSet a) -> String
wNoThunks :: Context -> OSet a -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall a. NoThunks a => Context -> OSet a -> IO (Maybe ThunkInfo)
noThunks :: Context -> OSet a -> IO (Maybe ThunkInfo)
$cnoThunks :: forall a. NoThunks a => Context -> OSet a -> IO (Maybe ThunkInfo)
NoThunks, forall a. NFData a => OSet a -> ()
forall a. (a -> ()) -> NFData a
rnf :: OSet a -> ()
$crnf :: forall a. NFData a => OSet a -> ()
NFData)
instance Ord a => Semigroup (OSet a) where
<> :: OSet a -> OSet a -> OSet a
(<>) = forall a. Ord a => OSet a -> OSet a -> OSet a
(|><)
instance Ord a => Monoid (OSet a) where
mempty :: OSet a
mempty = forall a. OSet a
empty
instance Ord a => GHC.IsList (OSet a) where
type Item (OSet a) = a
fromList :: [Item (OSet a)] -> OSet a
fromList = forall a. Ord a => [a] -> OSet a
fromList
toList :: OSet a -> [Item (OSet a)]
toList = forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
instance Foldable OSet where
foldMap :: forall m a. Monoid m => (a -> m) -> OSet a -> m
foldMap a -> m
f = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
F.foldMap a -> m
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldMap #-}
foldr :: forall a b. (a -> b -> b) -> b -> OSet a -> b
foldr a -> b -> b
f b
z = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr a -> b -> b
f b
z forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldr #-}
foldl :: forall b a. (b -> a -> b) -> b -> OSet a -> b
foldl b -> a -> b
f b
z = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl b -> a -> b
f b
z forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldl #-}
foldr' :: forall a b. (a -> b -> b) -> b -> OSet a -> b
foldr' a -> b -> b
f b
z = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr' a -> b -> b
f b
z forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldr' #-}
foldl' :: forall b a. (b -> a -> b) -> b -> OSet a -> b
foldl' b -> a -> b
f b
z = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' b -> a -> b
f b
z forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldl' #-}
foldr1 :: forall a. (a -> a -> a) -> OSet a -> a
foldr1 a -> a -> a
f = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
F.foldr1 a -> a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldr1 #-}
foldl1 :: forall a. (a -> a -> a) -> OSet a -> a
foldl1 a -> a -> a
f = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
F.foldl1 a -> a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINEABLE foldl1 #-}
length :: forall a. OSet a -> Int
length = forall (t :: * -> *) a. Foldable t => t a -> Int
F.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINE length #-}
null :: forall a. OSet a -> Bool
null = forall (t :: * -> *) a. Foldable t => t a -> Bool
F.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. StrictSeq a -> Seq a
SSeq.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. OSet a -> StrictSeq a
osSSeq
{-# INLINE null #-}
instance EncCBOR a => EncCBOR (OSet a) where
encCBOR :: OSet a -> Encoding
encCBOR (OSet StrictSeq a
seq Set a
_set) = Word -> Encoding
encodeTag Word
setTag forall a. Semigroup a => a -> a -> a
<> forall a. (a -> Encoding) -> StrictSeq a -> Encoding
encodeStrictSeq forall a. EncCBOR a => a -> Encoding
encCBOR StrictSeq a
seq
instance (Show a, Ord a, DecCBOR a) => DecCBOR (OSet a) where
decCBOR :: forall s. Decoder s (OSet a)
decCBOR = forall s a b c.
Monoid b =>
(a -> b -> b) -> (b -> (Int, c)) -> Decoder s a -> Decoder s c
decodeSetLikeEnforceNoDuplicates (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Ord a => OSet a -> a -> OSet a
snoc) (\OSet a
oset -> (forall a. OSet a -> Int
size OSet a
oset, OSet a
oset)) forall a s. DecCBOR a => Decoder s a
decCBOR
instance ToJSON a => ToJSON (OSet a) where
toJSON :: OSet a -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList
invariantHolds :: OSet a -> Bool
invariantHolds :: forall a. OSet a -> Bool
invariantHolds (OSet StrictSeq a
seq Set a
set) = forall a. StrictSeq a -> Int
SSeq.length StrictSeq a
seq forall a. Eq a => a -> a -> Bool
== forall a. Set a -> Int
Set.size Set a
set
invariantHolds' :: Ord a => OSet a -> Bool
invariantHolds' :: forall a. Ord a => OSet a -> Bool
invariantHolds' oset :: OSet a
oset@(OSet StrictSeq a
seq Set a
set) =
forall a. OSet a -> Bool
invariantHolds OSet a
oset Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
set) (forall a. StrictSeq a -> Seq a
SSeq.fromStrict StrictSeq a
seq)
null :: OSet a -> Bool
null :: forall a. OSet a -> Bool
null (OSet StrictSeq a
_ Set a
set) = forall a. Set a -> Bool
Set.null Set a
set
size :: OSet a -> Int
size :: forall a. OSet a -> Int
size (OSet StrictSeq a
_ Set a
set) = forall a. Set a -> Int
Set.size Set a
set
empty :: OSet a
empty :: forall a. OSet a
empty = forall a. StrictSeq a -> Set a -> OSet a
OSet forall a. StrictSeq a
SSeq.Empty forall a. Set a
Set.empty
singleton :: a -> OSet a
singleton :: forall a. a -> OSet a
singleton !a
x = forall a. StrictSeq a -> Set a -> OSet a
OSet (forall a. a -> StrictSeq a
SSeq.singleton a
x) (forall a. a -> Set a
Set.singleton a
x)
lookup :: Int -> OSet a -> Maybe a
lookup :: forall a. Int -> OSet a -> Maybe a
lookup Int
i (OSet StrictSeq a
seq Set a
_set) = forall a. Int -> StrictSeq a -> Maybe a
SSeq.lookup Int
i StrictSeq a
seq
(!?) :: OSet a -> Int -> Maybe a
!? :: forall a. OSet a -> Int -> Maybe a
(!?) = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Int -> OSet a -> Maybe a
lookup
cons :: Ord a => a -> OSet a -> OSet a
cons :: forall a. Ord a => a -> OSet a -> OSet a
cons a
x oset :: OSet a
oset@(OSet StrictSeq a
seq Set a
set) =
if a
x forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
set
then OSet a
oset
else forall a. StrictSeq a -> Set a -> OSet a
OSet (a
x forall a. a -> StrictSeq a -> StrictSeq a
SSeq.<| StrictSeq a
seq) (a
x forall a. Ord a => a -> Set a -> Set a
`Set.insert` Set a
set)
(<|) :: Ord a => a -> OSet a -> OSet a
<| :: forall a. Ord a => a -> OSet a -> OSet a
(<|) = forall a. Ord a => a -> OSet a -> OSet a
cons
infixr 5 <|
snoc :: Ord a => OSet a -> a -> OSet a
snoc :: forall a. Ord a => OSet a -> a -> OSet a
snoc oset :: OSet a
oset@(OSet StrictSeq a
seq Set a
set) a
x =
if a
x forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
set
then OSet a
oset
else forall a. StrictSeq a -> Set a -> OSet a
OSet (StrictSeq a
seq forall a. StrictSeq a -> a -> StrictSeq a
SSeq.|> a
x) (a
x forall a. Ord a => a -> Set a -> Set a
`Set.insert` Set a
set)
(|>) :: Ord a => OSet a -> a -> OSet a
|> :: forall a. Ord a => OSet a -> a -> OSet a
(|>) = forall a. Ord a => OSet a -> a -> OSet a
snoc
infixl 5 |>
uncons :: Ord a => OSet a -> Maybe (a, OSet a)
uncons :: forall a. Ord a => OSet a -> Maybe (a, OSet a)
uncons (OSet StrictSeq a
seq Set a
set) = case StrictSeq a
seq of
StrictSeq a
SSeq.Empty -> forall a. Maybe a
Nothing
a
x SSeq.:<| StrictSeq a
xs' -> forall a. a -> Maybe a
Just (a
x, forall a. StrictSeq a -> Set a -> OSet a
OSet StrictSeq a
xs' (a
x forall a. Ord a => a -> Set a -> Set a
`Set.delete` Set a
set))
unsnoc :: Ord a => OSet a -> Maybe (OSet a, a)
unsnoc :: forall a. Ord a => OSet a -> Maybe (OSet a, a)
unsnoc (OSet StrictSeq a
seq Set a
set) = case StrictSeq a
seq of
StrictSeq a
SSeq.Empty -> forall a. Maybe a
Nothing
StrictSeq a
xs' SSeq.:|> a
x -> forall a. a -> Maybe a
Just (forall a. StrictSeq a -> Set a -> OSet a
OSet StrictSeq a
xs' (a
x forall a. Ord a => a -> Set a -> Set a
`Set.delete` Set a
set), a
x)
fromList :: Ord a => [a] -> OSet a
fromList :: forall a. Ord a => [a] -> OSet a
fromList = forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> OSet a
fromFoldable
fromFoldable :: (Foldable f, Ord a) => f a -> OSet a
fromFoldable :: forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> OSet a
fromFoldable = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' forall a. Ord a => OSet a -> a -> OSet a
snoc forall a. OSet a
empty
fromStrictSeq :: Ord a => SSeq.StrictSeq a -> OSet a
fromStrictSeq :: forall a. Ord a => StrictSeq a -> OSet a
fromStrictSeq = forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> OSet a
fromFoldable
fromFoldableDuplicates :: (Foldable f, Ord a) => f a -> (Set.Set a, OSet a)
fromFoldableDuplicates :: forall (f :: * -> *) a.
(Foldable f, Ord a) =>
f a -> (Set a, OSet a)
fromFoldableDuplicates = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' forall a. Ord a => (Set a, OSet a) -> a -> (Set a, OSet a)
snoc' (forall a. Set a
Set.empty, forall a. OSet a
empty)
where
snoc' :: Ord a => (Set.Set a, OSet a) -> a -> (Set.Set a, OSet a)
snoc' :: forall a. Ord a => (Set a, OSet a) -> a -> (Set a, OSet a)
snoc' (!Set a
duplicates, !oset :: OSet a
oset@(OSet StrictSeq a
seq Set a
set)) a
x =
if a
x forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
set
then (a
x forall a. Ord a => a -> Set a -> Set a
`Set.insert` Set a
duplicates, OSet a
oset)
else (Set a
duplicates, forall a. StrictSeq a -> Set a -> OSet a
OSet (StrictSeq a
seq forall a. StrictSeq a -> a -> StrictSeq a
SSeq.|> a
x) (a
x forall a. Ord a => a -> Set a -> Set a
`Set.insert` Set a
set))
fromStrictSeqDuplicates :: Ord a => SSeq.StrictSeq a -> (Set.Set a, OSet a)
fromStrictSeqDuplicates :: forall a. Ord a => StrictSeq a -> (Set a, OSet a)
fromStrictSeqDuplicates = forall (f :: * -> *) a.
(Foldable f, Ord a) =>
f a -> (Set a, OSet a)
fromFoldableDuplicates
toStrictSeq :: OSet a -> SSeq.StrictSeq a
toStrictSeq :: forall a. OSet a -> StrictSeq a
toStrictSeq = forall a. OSet a -> StrictSeq a
osSSeq
toSet :: OSet a -> Set.Set a
toSet :: forall a. OSet a -> Set a
toSet = forall a. OSet a -> Set a
osSet
fromSet :: Set.Set a -> OSet a
fromSet :: forall a. Set a -> OSet a
fromSet Set a
set = forall a. StrictSeq a -> Set a -> OSet a
OSet (forall a. [a] -> StrictSeq a
SSeq.fromList forall a b. (a -> b) -> a -> b
$ forall a. Set a -> [a]
Set.elems Set a
set) Set a
set
member :: Ord a => a -> OSet a -> Bool
member :: forall a. Ord a => a -> OSet a -> Bool
member a
x (OSet StrictSeq a
_seq Set a
set) = a
x forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
set
filter :: Ord a => (a -> Bool) -> OSet a -> OSet a
filter :: forall a. Ord a => (a -> Bool) -> OSet a -> OSet a
filter a -> Bool
f = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (\OSet a
xs a
x -> if a -> Bool
f a
x then OSet a
xs forall a. Ord a => OSet a -> a -> OSet a
|> a
x else OSet a
xs) forall a. OSet a
empty
pattern Empty :: OSet a
pattern $bEmpty :: forall a. OSet a
$mEmpty :: forall {r} {a}. OSet a -> ((# #) -> r) -> ((# #) -> r) -> r
Empty <- (null -> True)
where
Empty = forall a. OSet a
empty
pattern (:<|:) :: Ord a => a -> OSet a -> OSet a
pattern x $b:<|: :: forall a. Ord a => a -> OSet a -> OSet a
$m:<|: :: forall {r} {a}.
Ord a =>
OSet a -> (a -> OSet a -> r) -> ((# #) -> r) -> r
:<|: xs <- (uncons -> Just (x, xs))
where
a
x :<|: OSet a
xs = a
x forall a. Ord a => a -> OSet a -> OSet a
<| OSet a
xs
infixr 5 :<|:
pattern (:|>:) :: Ord a => OSet a -> a -> OSet a
pattern xs $b:|>: :: forall a. Ord a => OSet a -> a -> OSet a
$m:|>: :: forall {r} {a}.
Ord a =>
OSet a -> (OSet a -> a -> r) -> ((# #) -> r) -> r
:|>: x <- (unsnoc -> Just (xs, x))
where
OSet a
xs :|>: a
x = OSet a
xs forall a. Ord a => OSet a -> a -> OSet a
|> a
x
infixl 5 :|>:
{-# COMPLETE Empty, (:|>:) #-}
{-# COMPLETE Empty, (:<|:) #-}
(|><) :: Ord a => OSet a -> OSet a -> OSet a
OSet a
osetl |>< :: forall a. Ord a => OSet a -> OSet a -> OSet a
|>< OSet a
osetr = case OSet a
osetr of
OSet a
Empty -> OSet a
osetl
a
r :<|: OSet a
rs -> (OSet a
osetl forall a. Ord a => OSet a -> a -> OSet a
|> a
r) forall a. Ord a => OSet a -> OSet a -> OSet a
|>< OSet a
rs
infixl 5 |><
(><|) :: Ord a => OSet a -> OSet a -> OSet a
OSet a
osetl ><| :: forall a. Ord a => OSet a -> OSet a -> OSet a
><| OSet a
osetr = case OSet a
osetl of
OSet a
Empty -> OSet a
osetr
OSet a
ls :|>: a
l -> OSet a
ls forall a. Ord a => OSet a -> OSet a -> OSet a
><| (a
l forall a. Ord a => a -> OSet a -> OSet a
<| OSet a
osetr)
infixr 5 ><|