{-# LANGUAGE Safe #-}

module Map where

import Data.Eq (Eq)
import Data.Foldable qualified as Seq
  ( toList,
  )
import Data.HashMap.Strict qualified as HashMap
  ( empty,
    lookup,
    singleton,
    union,
    unionWith,
  )
import Data.Hashable (Hashable)
import Data.Map.Strict qualified as OrdMap
  ( empty,
    lookup,
    singleton,
    union,
    unionWith,
  )
import Data.Maybe (Maybe, maybe)
import Data.Ord (Ord)
import Data.Sequence qualified as Seq
  ( singleton,
    (><),
  )

data Map f a b = forall map.
  Map
  { ()
empty :: map,
    ()
singleton :: a -> b -> map,
    ()
union :: map -> map -> map,
    ()
lookup :: map -> a -> f b
  }

type SingleMap = Map Maybe

type MultiMap = Map []

hashSingleMap :: (Eq a, Hashable a) => SingleMap a b
hashSingleMap :: forall a b. (Eq a, Hashable a) => SingleMap a b
hashSingleMap = Map {HashMap a b
forall {k} {v}. HashMap k v
empty :: HashMap a b
empty :: forall {k} {v}. HashMap k v
empty, a -> b -> HashMap a b
forall {v}. a -> v -> HashMap a v
singleton :: a -> b -> HashMap a b
singleton :: forall {v}. a -> v -> HashMap a v
singleton, HashMap a b -> HashMap a b -> HashMap a b
forall {v}. HashMap a v -> HashMap a v -> HashMap a v
union :: HashMap a b -> HashMap a b -> HashMap a b
union :: forall {v}. HashMap a v -> HashMap a v -> HashMap a v
union, HashMap a b -> a -> Maybe b
forall {k} {v}. Hashable k => HashMap k v -> k -> Maybe v
lookup :: HashMap a b -> a -> Maybe b
lookup :: forall {k} {v}. Hashable k => HashMap k v -> k -> Maybe v
lookup}
  where
    empty :: HashMap k v
empty = HashMap k v
forall {k} {v}. HashMap k v
HashMap.empty
    singleton :: a -> v -> HashMap a v
singleton = a -> v -> HashMap a v
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton
    union :: HashMap a v -> HashMap a v -> HashMap a v
union = HashMap a v -> HashMap a v -> HashMap a v
forall k v. Eq k => HashMap k v -> HashMap k v -> HashMap k v
HashMap.union
    lookup :: HashMap k v -> k -> Maybe v
lookup HashMap k v
m k
a = k -> HashMap k v -> Maybe v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup k
a HashMap k v
m

hashMultiMap :: (Eq a, Hashable a) => MultiMap a b
hashMultiMap :: forall a b. (Eq a, Hashable a) => MultiMap a b
hashMultiMap = Map {HashMap a (Seq b)
forall {k} {v}. HashMap k v
empty :: HashMap a (Seq b)
empty :: forall {k} {v}. HashMap k v
empty, a -> b -> HashMap a (Seq b)
forall {a}. a -> a -> HashMap a (Seq a)
singleton :: a -> b -> HashMap a (Seq b)
singleton :: forall {a}. a -> a -> HashMap a (Seq a)
singleton, HashMap a (Seq b) -> HashMap a (Seq b) -> HashMap a (Seq b)
forall {a}.
HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
union :: HashMap a (Seq b) -> HashMap a (Seq b) -> HashMap a (Seq b)
union :: forall {a}.
HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
union, HashMap a (Seq b) -> a -> [b]
forall {a}. HashMap a (Seq a) -> a -> [a]
lookup :: HashMap a (Seq b) -> a -> [b]
lookup :: forall {a}. HashMap a (Seq a) -> a -> [a]
lookup}
  where
    empty :: HashMap k v
empty = HashMap k v
forall {k} {v}. HashMap k v
HashMap.empty
    singleton :: a -> a -> HashMap a (Seq a)
singleton = \a
a a
b -> a -> Seq a -> HashMap a (Seq a)
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton a
a (a -> Seq a
forall a. a -> Seq a
Seq.singleton a
b)
    union :: HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
union = (Seq a -> Seq a -> Seq a)
-> HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
forall k v.
Eq k =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
HashMap.unionWith Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
(Seq.><)
    lookup :: HashMap a (Seq a) -> a -> [a]
lookup = \HashMap a (Seq a)
m a
a -> [a] -> (Seq a -> [a]) -> Maybe (Seq a) -> [a]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Seq a -> [a]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Seq.toList (a -> HashMap a (Seq a) -> Maybe (Seq a)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup a
a HashMap a (Seq a)
m)

ordSingleMap :: Ord a => SingleMap a b
ordSingleMap :: forall a b. Ord a => SingleMap a b
ordSingleMap = Map {Map a b
forall {k} {a}. Map k a
empty :: Map a b
empty :: forall {k} {a}. Map k a
empty, a -> b -> Map a b
forall {k} {a}. k -> a -> Map k a
singleton :: a -> b -> Map a b
singleton :: forall {k} {a}. k -> a -> Map k a
singleton, Map a b -> Map a b -> Map a b
forall {a}. Map a a -> Map a a -> Map a a
union :: Map a b -> Map a b -> Map a b
union :: forall {a}. Map a a -> Map a a -> Map a a
union, Map a b -> a -> Maybe b
forall {k} {a}. Ord k => Map k a -> k -> Maybe a
lookup :: Map a b -> a -> Maybe b
lookup :: forall {k} {a}. Ord k => Map k a -> k -> Maybe a
lookup}
  where
    empty :: Map k a
empty = Map k a
forall {k} {a}. Map k a
OrdMap.empty
    singleton :: k -> a -> Map k a
singleton = k -> a -> Map k a
forall {k} {a}. k -> a -> Map k a
OrdMap.singleton
    union :: Map a a -> Map a a -> Map a a
union = Map a a -> Map a a -> Map a a
forall k a. Ord k => Map k a -> Map k a -> Map k a
OrdMap.union
    lookup :: Map k a -> k -> Maybe a
lookup Map k a
m k
a = k -> Map k a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
OrdMap.lookup k
a Map k a
m

ordMultiMap :: Ord a => MultiMap a b
ordMultiMap :: forall a b. Ord a => MultiMap a b
ordMultiMap = Map {Map a (Seq b)
forall {k} {a}. Map k a
empty :: Map a (Seq b)
empty :: forall {k} {a}. Map k a
empty, a -> b -> Map a (Seq b)
forall {k} {a}. k -> a -> Map k (Seq a)
singleton :: a -> b -> Map a (Seq b)
singleton :: forall {k} {a}. k -> a -> Map k (Seq a)
singleton, Map a (Seq b) -> Map a (Seq b) -> Map a (Seq b)
forall {a}. Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
union :: Map a (Seq b) -> Map a (Seq b) -> Map a (Seq b)
union :: forall {a}. Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
union, Map a (Seq b) -> a -> [b]
forall {a}. Map a (Seq a) -> a -> [a]
lookup :: Map a (Seq b) -> a -> [b]
lookup :: forall {a}. Map a (Seq a) -> a -> [a]
lookup}
  where
    empty :: Map k a
empty = Map k a
forall {k} {a}. Map k a
OrdMap.empty
    singleton :: k -> a -> Map k (Seq a)
singleton = \k
a a
b -> k -> Seq a -> Map k (Seq a)
forall {k} {a}. k -> a -> Map k a
OrdMap.singleton k
a (a -> Seq a
forall a. a -> Seq a
Seq.singleton a
b)
    union :: Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
union = (Seq a -> Seq a -> Seq a)
-> Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
OrdMap.unionWith Seq a -> Seq a -> Seq a
forall a. Seq a -> Seq a -> Seq a
(Seq.><)
    lookup :: Map a (Seq a) -> a -> [a]
lookup = \Map a (Seq a)
m a
a -> [a] -> (Seq a -> [a]) -> Maybe (Seq a) -> [a]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Seq a -> [a]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Seq.toList (a -> Map a (Seq a) -> Maybe (Seq a)
forall k a. Ord k => k -> Map k a -> Maybe a
OrdMap.lookup a
a Map a (Seq a)
m)