{-# 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 :: SingleMap a b
hashSingleMap = Map :: forall (f :: * -> *) a b map.
map
-> (a -> b -> map)
-> (map -> map -> map)
-> (map -> a -> f b)
-> Map f a b
Map{ HashMap a b
forall k v. HashMap k v
empty :: forall k v. HashMap k v
empty :: HashMap a b
empty, a -> b -> HashMap a b
forall v. a -> v -> HashMap a v
singleton :: forall v. a -> v -> HashMap a v
singleton :: a -> b -> HashMap a b
singleton, HashMap a b -> HashMap a b -> HashMap a b
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, HashMap a b -> a -> Maybe b
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 = 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, 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 = 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 :: MultiMap a b
hashMultiMap = Map :: forall (f :: * -> *) a b map.
map
-> (a -> b -> map)
-> (map -> map -> map)
-> (map -> a -> f b)
-> Map f a b
Map{ HashMap a (Seq b)
forall k v. HashMap k v
empty :: forall k v. HashMap k v
empty :: HashMap a (Seq b)
empty, a -> b -> HashMap a (Seq b)
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, 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 :: 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, HashMap a (Seq b) -> a -> [b]
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 = 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, Hashable 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 (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 :: SingleMap a b
ordSingleMap = Map :: forall (f :: * -> *) a b map.
map
-> (a -> b -> map)
-> (map -> map -> map)
-> (map -> a -> f b)
-> Map f a b
Map{ Map a b
forall k a. Map k a
empty :: forall k a. Map k a
empty :: Map a b
empty, a -> b -> Map a b
forall k a. k -> a -> Map k a
singleton :: forall k a. k -> a -> Map k a
singleton :: a -> b -> Map a b
singleton, Map a b -> Map a b -> Map a b
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, Map a b -> a -> Maybe b
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 = 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 :: MultiMap a b
ordMultiMap = Map :: forall (f :: * -> *) a b map.
map
-> (a -> b -> map)
-> (map -> map -> map)
-> (map -> a -> f b)
-> Map f a b
Map{ Map a (Seq b)
forall k a. Map k a
empty :: forall k a. Map k a
empty :: Map a (Seq b)
empty, a -> b -> Map a (Seq b)
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, 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 :: 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, Map a (Seq b) -> a -> [b]
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 = 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 (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)