{-# language Safe #-}

module Map where

import Data.Eq       ( Eq )
import Data.Hashable ( Hashable )
import Data.Maybe    ( Maybe, maybe )
import Data.Ord      ( Ord )

import qualified Data.Foldable
    as Seq (toList)

import qualified Data.HashMap.Strict
    as HashMap (lookup, singleton, empty, union, unionWith)

import qualified Data.Map.Strict
    as OrdMap (lookup, singleton, empty, union, unionWith)

import qualified Data.Sequence
    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)