-- |
-- Copyright: © 2022–2024 Jonathan Knowles
-- License: Apache-2.0
--
-- A __lawful__ implementation of 'MultiMap', implemented in terms of
-- 'MonoidMap' and 'Set'.
--
module Examples.MultiMap.Instances.MultiMap4 where

import Prelude

import Data.MonoidMap
    ( MonoidMap )
import Data.Set
    ( Set )

import qualified Data.MonoidMap as MonoidMap
import qualified Data.Set as Set
import qualified Examples.MultiMap.Class as Class

newtype MultiMap4 k v = MultiMap (MonoidMap k (Set v))
    deriving stock (MultiMap4 k v -> MultiMap4 k v -> Bool
(MultiMap4 k v -> MultiMap4 k v -> Bool)
-> (MultiMap4 k v -> MultiMap4 k v -> Bool) -> Eq (MultiMap4 k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. (Eq k, Eq v) => MultiMap4 k v -> MultiMap4 k v -> Bool
$c== :: forall k v. (Eq k, Eq v) => MultiMap4 k v -> MultiMap4 k v -> Bool
== :: MultiMap4 k v -> MultiMap4 k v -> Bool
$c/= :: forall k v. (Eq k, Eq v) => MultiMap4 k v -> MultiMap4 k v -> Bool
/= :: MultiMap4 k v -> MultiMap4 k v -> Bool
Eq, Int -> MultiMap4 k v -> ShowS
[MultiMap4 k v] -> ShowS
MultiMap4 k v -> String
(Int -> MultiMap4 k v -> ShowS)
-> (MultiMap4 k v -> String)
-> ([MultiMap4 k v] -> ShowS)
-> Show (MultiMap4 k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> MultiMap4 k v -> ShowS
forall k v. (Show k, Show v) => [MultiMap4 k v] -> ShowS
forall k v. (Show k, Show v) => MultiMap4 k v -> String
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> MultiMap4 k v -> ShowS
showsPrec :: Int -> MultiMap4 k v -> ShowS
$cshow :: forall k v. (Show k, Show v) => MultiMap4 k v -> String
show :: MultiMap4 k v -> String
$cshowList :: forall k v. (Show k, Show v) => [MultiMap4 k v] -> ShowS
showList :: [MultiMap4 k v] -> ShowS
Show)

instance (Ord k, Ord v) => Class.MultiMap MultiMap4 k v where

    fromList :: [(k, Set v)] -> MultiMap4 k v
fromList = MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap (MonoidMap k (Set v) -> MultiMap4 k v)
-> ([(k, Set v)] -> MonoidMap k (Set v))
-> [(k, Set v)]
-> MultiMap4 k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set v -> Set v -> Set v) -> [(k, Set v)] -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v) =>
(v -> v -> v) -> [(k, v)] -> MonoidMap k v
MonoidMap.fromListWith Set v -> Set v -> Set v
forall a. Semigroup a => a -> a -> a
(<>)

    toList :: MultiMap4 k v -> [(k, Set v)]
toList (MultiMap MonoidMap k (Set v)
m) = MonoidMap k (Set v) -> [(k, Set v)]
forall k v. MonoidMap k v -> [(k, v)]
MonoidMap.toList MonoidMap k (Set v)
m

    empty :: MultiMap4 k v
empty = MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap MonoidMap k (Set v)
forall k v. MonoidMap k v
MonoidMap.empty

    lookup :: k -> MultiMap4 k v -> Set v
lookup k
k (MultiMap MonoidMap k (Set v)
m) = k -> MonoidMap k (Set v) -> Set v
forall k v. (Ord k, Monoid v) => k -> MonoidMap k v -> v
MonoidMap.get k
k MonoidMap k (Set v)
m

    null :: MultiMap4 k v -> Bool
null (MultiMap MonoidMap k (Set v)
m) = MonoidMap k (Set v) -> Bool
forall k v. MonoidMap k v -> Bool
MonoidMap.null MonoidMap k (Set v)
m

    nonNull :: MultiMap4 k v -> Bool
nonNull (MultiMap MonoidMap k (Set v)
m) = MonoidMap k (Set v) -> Bool
forall k v. MonoidMap k v -> Bool
MonoidMap.nonNull MonoidMap k (Set v)
m

    nonNullKey :: k -> MultiMap4 k v -> Bool
nonNullKey k
k (MultiMap MonoidMap k (Set v)
m) = k -> MonoidMap k (Set v) -> Bool
forall k v. Ord k => k -> MonoidMap k v -> Bool
MonoidMap.nonNullKey k
k MonoidMap k (Set v)
m

    nonNullKeys :: MultiMap4 k v -> Set k
nonNullKeys (MultiMap MonoidMap k (Set v)
m) = MonoidMap k (Set v) -> Set k
forall k v. MonoidMap k v -> Set k
MonoidMap.nonNullKeys MonoidMap k (Set v)
m

    nonNullCount :: MultiMap4 k v -> Int
nonNullCount (MultiMap MonoidMap k (Set v)
m) = MonoidMap k (Set v) -> Int
forall k v. MonoidMap k v -> Int
MonoidMap.nonNullCount MonoidMap k (Set v)
m

    isSubmapOf :: MultiMap4 k v -> MultiMap4 k v -> Bool
isSubmapOf (MultiMap MonoidMap k (Set v)
m1) (MultiMap MonoidMap k (Set v)
m2) = MonoidMap k (Set v)
m1 MonoidMap k (Set v) -> MonoidMap k (Set v) -> Bool
forall k v.
(Ord k, Monoid v, Reductive v) =>
MonoidMap k v -> MonoidMap k v -> Bool
`MonoidMap.isSubmapOf` MonoidMap k (Set v)
m2

    update :: k -> Set v -> MultiMap4 k v -> MultiMap4 k v
update k
k Set v
vs (MultiMap MonoidMap k (Set v)
m) =
        MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap (k -> Set v -> MonoidMap k (Set v) -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v) =>
k -> v -> MonoidMap k v -> MonoidMap k v
MonoidMap.set k
k Set v
vs MonoidMap k (Set v)
m)

    insert :: k -> Set v -> MultiMap4 k v -> MultiMap4 k v
insert k
k Set v
vs (MultiMap MonoidMap k (Set v)
m) =
        MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap ((Set v -> Set v) -> k -> MonoidMap k (Set v) -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v) =>
(v -> v) -> k -> MonoidMap k v -> MonoidMap k v
MonoidMap.adjust (Set v -> Set v -> Set v
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set v
vs) k
k MonoidMap k (Set v)
m)

    remove :: k -> Set v -> MultiMap4 k v -> MultiMap4 k v
remove k
k Set v
vs (MultiMap MonoidMap k (Set v)
m) =
        MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap ((Set v -> Set v) -> k -> MonoidMap k (Set v) -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v) =>
(v -> v) -> k -> MonoidMap k v -> MonoidMap k v
MonoidMap.adjust (Set v -> Set v -> Set v
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` Set v
vs) k
k MonoidMap k (Set v)
m)

    union :: MultiMap4 k v -> MultiMap4 k v -> MultiMap4 k v
union (MultiMap MonoidMap k (Set v)
m1) (MultiMap MonoidMap k (Set v)
m2) =
        MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap (MonoidMap k (Set v) -> MonoidMap k (Set v) -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v, LCMMonoid v) =>
MonoidMap k v -> MonoidMap k v -> MonoidMap k v
MonoidMap.union MonoidMap k (Set v)
m1 MonoidMap k (Set v)
m2)

    intersection :: MultiMap4 k v -> MultiMap4 k v -> MultiMap4 k v
intersection (MultiMap MonoidMap k (Set v)
m1) (MultiMap MonoidMap k (Set v)
m2) =
        MonoidMap k (Set v) -> MultiMap4 k v
forall k v. MonoidMap k (Set v) -> MultiMap4 k v
MultiMap (MonoidMap k (Set v) -> MonoidMap k (Set v) -> MonoidMap k (Set v)
forall k v.
(Ord k, MonoidNull v, GCDMonoid v) =>
MonoidMap k v -> MonoidMap k v -> MonoidMap k v
MonoidMap.intersection MonoidMap k (Set v)
m1 MonoidMap k (Set v)
m2)