{-# 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 {forall {k} {v}. HashMap k v
empty :: forall {k} {v}. HashMap k v
empty :: HashMap a b
empty, forall {v}. a -> v -> HashMap a v
singleton :: forall {v}. a -> v -> HashMap a v
singleton :: a -> b -> HashMap a b
singleton, forall {v}. HashMap a v -> HashMap a v -> HashMap a v
union :: forall {v}. HashMap a v -> HashMap a v -> HashMap a v
union :: HashMap a b -> HashMap a b -> HashMap a b
union, forall {k} {v}. Hashable k => HashMap k v -> k -> Maybe v
lookup :: forall {k} {v}. Hashable k => HashMap k v -> k -> Maybe v
lookup :: HashMap a b -> a -> Maybe b
lookup}
  where
    empty :: HashMap k v
empty = forall {k} {v}. HashMap k v
HashMap.empty
    singleton :: a -> v -> HashMap a v
singleton = forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton
    union :: HashMap a v -> HashMap a v -> HashMap a v
union = forall k v.
(Eq k, Hashable 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 = 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 {forall {k} {v}. HashMap k v
empty :: forall {k} {v}. HashMap k v
empty :: HashMap a (Seq b)
empty, forall {a}. a -> a -> HashMap a (Seq a)
singleton :: forall {a}. a -> a -> HashMap a (Seq a)
singleton :: a -> b -> HashMap a (Seq b)
singleton, forall {a}.
HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
union :: 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) -> a -> [a]
lookup :: forall {a}. HashMap a (Seq a) -> a -> [a]
lookup :: HashMap a (Seq b) -> a -> [b]
lookup}
  where
    empty :: HashMap k v
empty = forall {k} {v}. HashMap k v
HashMap.empty
    singleton :: a -> a -> HashMap a (Seq a)
singleton = \a
a a
b -> forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton a
a (forall a. a -> Seq a
Seq.singleton a
b)
    union :: HashMap a (Seq a) -> HashMap a (Seq a) -> HashMap a (Seq a)
union = forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
HashMap.unionWith forall a. Seq a -> Seq a -> Seq a
(Seq.><)
    lookup :: HashMap a (Seq a) -> a -> [a]
lookup = \HashMap a (Seq a)
m a
a -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] forall (t :: * -> *) a. Foldable t => t a -> [a]
Seq.toList (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 {forall {k} {a}. Map k a
empty :: forall {k} {a}. Map k a
empty :: Map a b
empty, forall {k} {a}. k -> a -> Map k a
singleton :: forall {k} {a}. k -> a -> Map k a
singleton :: a -> b -> Map a b
singleton, forall {a}. Map a a -> Map a a -> Map a a
union :: forall {a}. Map a a -> Map a a -> Map a a
union :: Map a b -> Map a b -> Map a b
union, forall {k} {a}. Ord k => Map k a -> k -> Maybe a
lookup :: forall {k} {a}. Ord k => Map k a -> k -> Maybe a
lookup :: Map a b -> a -> Maybe b
lookup}
  where
    empty :: Map k a
empty = forall {k} {a}. Map k a
OrdMap.empty
    singleton :: k -> a -> Map k a
singleton = forall {k} {a}. k -> a -> Map k a
OrdMap.singleton
    union :: Map a a -> Map a a -> Map a a
union = 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 = 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 {forall {k} {a}. Map k a
empty :: forall {k} {a}. Map k a
empty :: Map a (Seq b)
empty, forall {k} {a}. k -> a -> Map k (Seq a)
singleton :: forall {k} {a}. k -> a -> Map k (Seq a)
singleton :: a -> b -> Map a (Seq b)
singleton, forall {a}. Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
union :: 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) -> a -> [a]
lookup :: forall {a}. Map a (Seq a) -> a -> [a]
lookup :: Map a (Seq b) -> a -> [b]
lookup}
  where
    empty :: Map k a
empty = forall {k} {a}. Map k a
OrdMap.empty
    singleton :: k -> a -> Map k (Seq a)
singleton = \k
a a
b -> forall {k} {a}. k -> a -> Map k a
OrdMap.singleton k
a (forall a. a -> Seq a
Seq.singleton a
b)
    union :: Map a (Seq a) -> Map a (Seq a) -> Map a (Seq a)
union = forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
OrdMap.unionWith forall a. Seq a -> Seq a -> Seq a
(Seq.><)
    lookup :: Map a (Seq a) -> a -> [a]
lookup = \Map a (Seq a)
m a
a -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] forall (t :: * -> *) a. Foldable t => t a -> [a]
Seq.toList (forall k a. Ord k => k -> Map k a -> Maybe a
OrdMap.lookup a
a Map a (Seq a)
m)