-- | Non-empty hash maps.
module Data.HashMap.Strict.NonEmpty
  ( -- * Type
    NEHashMap,

    -- * Construction and conversions
    singleton,
    fromHashMap,
    fromList,
    fromNonEmpty,
    toHashMap,
    toList,
    toNonEmpty,

    -- * Basic interface
    lookup,
    (!?),
    keys,

    -- * Combine
    union,
    unionWith,

    -- * Transformations
    mapKeys,

    -- * Predicates
    isInverseOf,
  )
where

import Control.DeepSeq (NFData)
import Data.Aeson (FromJSON, ToJSON)
import Data.HashMap.Strict (HashMap)
import Data.HashMap.Strict qualified as M
import Data.HashMap.Strict.Extended qualified as Extended
import Data.Hashable (Hashable)
import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified as NE
import Prelude hiding (lookup)

-------------------------------------------------------------------------------

-- | A non-empty hashmap is a wrapper around a normal hashmap, that
-- only provides a restricted set of functionalities. It doesn't
-- provide a 'Monoid' instance, nor an 'empty' function.
newtype NEHashMap k v = NEHashMap {NEHashMap k v -> HashMap k v
unNEHashMap :: HashMap k v}
  deriving newtype (Int -> NEHashMap k v -> ShowS
[NEHashMap k v] -> ShowS
NEHashMap k v -> String
(Int -> NEHashMap k v -> ShowS)
-> (NEHashMap k v -> String)
-> ([NEHashMap k v] -> ShowS)
-> Show (NEHashMap k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> NEHashMap k v -> ShowS
forall k v. (Show k, Show v) => [NEHashMap k v] -> ShowS
forall k v. (Show k, Show v) => NEHashMap k v -> String
showList :: [NEHashMap k v] -> ShowS
$cshowList :: forall k v. (Show k, Show v) => [NEHashMap k v] -> ShowS
show :: NEHashMap k v -> String
$cshow :: forall k v. (Show k, Show v) => NEHashMap k v -> String
showsPrec :: Int -> NEHashMap k v -> ShowS
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> NEHashMap k v -> ShowS
Show, NEHashMap k v -> NEHashMap k v -> Bool
(NEHashMap k v -> NEHashMap k v -> Bool)
-> (NEHashMap k v -> NEHashMap k v -> Bool) -> Eq (NEHashMap k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. (Eq k, Eq v) => NEHashMap k v -> NEHashMap k v -> Bool
/= :: NEHashMap k v -> NEHashMap k v -> Bool
$c/= :: forall k v. (Eq k, Eq v) => NEHashMap k v -> NEHashMap k v -> Bool
== :: NEHashMap k v -> NEHashMap k v -> Bool
$c== :: forall k v. (Eq k, Eq v) => NEHashMap k v -> NEHashMap k v -> Bool
Eq, Value -> Parser [NEHashMap k v]
Value -> Parser (NEHashMap k v)
(Value -> Parser (NEHashMap k v))
-> (Value -> Parser [NEHashMap k v]) -> FromJSON (NEHashMap k v)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
forall k v.
(FromJSON v, FromJSONKey k, Eq k, Hashable k) =>
Value -> Parser [NEHashMap k v]
forall k v.
(FromJSON v, FromJSONKey k, Eq k, Hashable k) =>
Value -> Parser (NEHashMap k v)
parseJSONList :: Value -> Parser [NEHashMap k v]
$cparseJSONList :: forall k v.
(FromJSON v, FromJSONKey k, Eq k, Hashable k) =>
Value -> Parser [NEHashMap k v]
parseJSON :: Value -> Parser (NEHashMap k v)
$cparseJSON :: forall k v.
(FromJSON v, FromJSONKey k, Eq k, Hashable k) =>
Value -> Parser (NEHashMap k v)
FromJSON, Int -> NEHashMap k v -> Int
NEHashMap k v -> Int
(Int -> NEHashMap k v -> Int)
-> (NEHashMap k v -> Int) -> Hashable (NEHashMap k v)
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall k v. (Hashable k, Hashable v) => Int -> NEHashMap k v -> Int
forall k v. (Hashable k, Hashable v) => NEHashMap k v -> Int
hash :: NEHashMap k v -> Int
$chash :: forall k v. (Hashable k, Hashable v) => NEHashMap k v -> Int
hashWithSalt :: Int -> NEHashMap k v -> Int
$chashWithSalt :: forall k v. (Hashable k, Hashable v) => Int -> NEHashMap k v -> Int
Hashable, NEHashMap k v -> ()
(NEHashMap k v -> ()) -> NFData (NEHashMap k v)
forall a. (a -> ()) -> NFData a
forall k v. (NFData k, NFData v) => NEHashMap k v -> ()
rnf :: NEHashMap k v -> ()
$crnf :: forall k v. (NFData k, NFData v) => NEHashMap k v -> ()
NFData, Eq (NEHashMap k v)
Eq (NEHashMap k v)
-> (NEHashMap k v -> NEHashMap k v -> Ordering)
-> (NEHashMap k v -> NEHashMap k v -> Bool)
-> (NEHashMap k v -> NEHashMap k v -> Bool)
-> (NEHashMap k v -> NEHashMap k v -> Bool)
-> (NEHashMap k v -> NEHashMap k v -> Bool)
-> (NEHashMap k v -> NEHashMap k v -> NEHashMap k v)
-> (NEHashMap k v -> NEHashMap k v -> NEHashMap k v)
-> Ord (NEHashMap k v)
NEHashMap k v -> NEHashMap k v -> Bool
NEHashMap k v -> NEHashMap k v -> Ordering
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k v. (Ord k, Ord v) => Eq (NEHashMap k v)
forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Bool
forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Ordering
forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
min :: NEHashMap k v -> NEHashMap k v -> NEHashMap k v
$cmin :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
max :: NEHashMap k v -> NEHashMap k v -> NEHashMap k v
$cmax :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
>= :: NEHashMap k v -> NEHashMap k v -> Bool
$c>= :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Bool
> :: NEHashMap k v -> NEHashMap k v -> Bool
$c> :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Bool
<= :: NEHashMap k v -> NEHashMap k v -> Bool
$c<= :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Bool
< :: NEHashMap k v -> NEHashMap k v -> Bool
$c< :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Bool
compare :: NEHashMap k v -> NEHashMap k v -> Ordering
$ccompare :: forall k v.
(Ord k, Ord v) =>
NEHashMap k v -> NEHashMap k v -> Ordering
$cp1Ord :: forall k v. (Ord k, Ord v) => Eq (NEHashMap k v)
Ord, b -> NEHashMap k v -> NEHashMap k v
NonEmpty (NEHashMap k v) -> NEHashMap k v
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
(NEHashMap k v -> NEHashMap k v -> NEHashMap k v)
-> (NonEmpty (NEHashMap k v) -> NEHashMap k v)
-> (forall b. Integral b => b -> NEHashMap k v -> NEHashMap k v)
-> Semigroup (NEHashMap k v)
forall b. Integral b => b -> NEHashMap k v -> NEHashMap k v
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall k v.
(Eq k, Hashable k) =>
NonEmpty (NEHashMap k v) -> NEHashMap k v
forall k v.
(Eq k, Hashable k) =>
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
forall k v b.
(Eq k, Hashable k, Integral b) =>
b -> NEHashMap k v -> NEHashMap k v
stimes :: b -> NEHashMap k v -> NEHashMap k v
$cstimes :: forall k v b.
(Eq k, Hashable k, Integral b) =>
b -> NEHashMap k v -> NEHashMap k v
sconcat :: NonEmpty (NEHashMap k v) -> NEHashMap k v
$csconcat :: forall k v.
(Eq k, Hashable k) =>
NonEmpty (NEHashMap k v) -> NEHashMap k v
<> :: NEHashMap k v -> NEHashMap k v -> NEHashMap k v
$c<> :: forall k v.
(Eq k, Hashable k) =>
NEHashMap k v -> NEHashMap k v -> NEHashMap k v
Semigroup, [NEHashMap k v] -> Value
[NEHashMap k v] -> Encoding
NEHashMap k v -> Value
NEHashMap k v -> Encoding
(NEHashMap k v -> Value)
-> (NEHashMap k v -> Encoding)
-> ([NEHashMap k v] -> Value)
-> ([NEHashMap k v] -> Encoding)
-> ToJSON (NEHashMap k v)
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
forall k v. (ToJSON v, ToJSONKey k) => [NEHashMap k v] -> Value
forall k v. (ToJSON v, ToJSONKey k) => [NEHashMap k v] -> Encoding
forall k v. (ToJSON v, ToJSONKey k) => NEHashMap k v -> Value
forall k v. (ToJSON v, ToJSONKey k) => NEHashMap k v -> Encoding
toEncodingList :: [NEHashMap k v] -> Encoding
$ctoEncodingList :: forall k v. (ToJSON v, ToJSONKey k) => [NEHashMap k v] -> Encoding
toJSONList :: [NEHashMap k v] -> Value
$ctoJSONList :: forall k v. (ToJSON v, ToJSONKey k) => [NEHashMap k v] -> Value
toEncoding :: NEHashMap k v -> Encoding
$ctoEncoding :: forall k v. (ToJSON v, ToJSONKey k) => NEHashMap k v -> Encoding
toJSON :: NEHashMap k v -> Value
$ctoJSON :: forall k v. (ToJSON v, ToJSONKey k) => NEHashMap k v -> Value
ToJSON)
  deriving stock (a -> NEHashMap k b -> NEHashMap k a
(a -> b) -> NEHashMap k a -> NEHashMap k b
(forall a b. (a -> b) -> NEHashMap k a -> NEHashMap k b)
-> (forall a b. a -> NEHashMap k b -> NEHashMap k a)
-> Functor (NEHashMap k)
forall a b. a -> NEHashMap k b -> NEHashMap k a
forall a b. (a -> b) -> NEHashMap k a -> NEHashMap k b
forall k a b. a -> NEHashMap k b -> NEHashMap k a
forall k a b. (a -> b) -> NEHashMap k a -> NEHashMap k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> NEHashMap k b -> NEHashMap k a
$c<$ :: forall k a b. a -> NEHashMap k b -> NEHashMap k a
fmap :: (a -> b) -> NEHashMap k a -> NEHashMap k b
$cfmap :: forall k a b. (a -> b) -> NEHashMap k a -> NEHashMap k b
Functor, NEHashMap k a -> Bool
(a -> m) -> NEHashMap k a -> m
(a -> b -> b) -> b -> NEHashMap k a -> b
(forall m. Monoid m => NEHashMap k m -> m)
-> (forall m a. Monoid m => (a -> m) -> NEHashMap k a -> m)
-> (forall m a. Monoid m => (a -> m) -> NEHashMap k a -> m)
-> (forall a b. (a -> b -> b) -> b -> NEHashMap k a -> b)
-> (forall a b. (a -> b -> b) -> b -> NEHashMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> NEHashMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> NEHashMap k a -> b)
-> (forall a. (a -> a -> a) -> NEHashMap k a -> a)
-> (forall a. (a -> a -> a) -> NEHashMap k a -> a)
-> (forall a. NEHashMap k a -> [a])
-> (forall a. NEHashMap k a -> Bool)
-> (forall a. NEHashMap k a -> Int)
-> (forall a. Eq a => a -> NEHashMap k a -> Bool)
-> (forall a. Ord a => NEHashMap k a -> a)
-> (forall a. Ord a => NEHashMap k a -> a)
-> (forall a. Num a => NEHashMap k a -> a)
-> (forall a. Num a => NEHashMap k a -> a)
-> Foldable (NEHashMap k)
forall a. Eq a => a -> NEHashMap k a -> Bool
forall a. Num a => NEHashMap k a -> a
forall a. Ord a => NEHashMap k a -> a
forall m. Monoid m => NEHashMap k m -> m
forall a. NEHashMap k a -> Bool
forall a. NEHashMap k a -> Int
forall a. NEHashMap k a -> [a]
forall a. (a -> a -> a) -> NEHashMap k a -> a
forall k a. Eq a => a -> NEHashMap k a -> Bool
forall k a. Num a => NEHashMap k a -> a
forall k a. Ord a => NEHashMap k a -> a
forall m a. Monoid m => (a -> m) -> NEHashMap k a -> m
forall k m. Monoid m => NEHashMap k m -> m
forall k a. NEHashMap k a -> Bool
forall k a. NEHashMap k a -> Int
forall k a. NEHashMap k a -> [a]
forall b a. (b -> a -> b) -> b -> NEHashMap k a -> b
forall a b. (a -> b -> b) -> b -> NEHashMap k a -> b
forall k a. (a -> a -> a) -> NEHashMap k a -> a
forall k m a. Monoid m => (a -> m) -> NEHashMap k a -> m
forall k b a. (b -> a -> b) -> b -> NEHashMap k a -> b
forall k a b. (a -> b -> b) -> b -> NEHashMap k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: NEHashMap k a -> a
$cproduct :: forall k a. Num a => NEHashMap k a -> a
sum :: NEHashMap k a -> a
$csum :: forall k a. Num a => NEHashMap k a -> a
minimum :: NEHashMap k a -> a
$cminimum :: forall k a. Ord a => NEHashMap k a -> a
maximum :: NEHashMap k a -> a
$cmaximum :: forall k a. Ord a => NEHashMap k a -> a
elem :: a -> NEHashMap k a -> Bool
$celem :: forall k a. Eq a => a -> NEHashMap k a -> Bool
length :: NEHashMap k a -> Int
$clength :: forall k a. NEHashMap k a -> Int
null :: NEHashMap k a -> Bool
$cnull :: forall k a. NEHashMap k a -> Bool
toList :: NEHashMap k a -> [a]
$ctoList :: forall k a. NEHashMap k a -> [a]
foldl1 :: (a -> a -> a) -> NEHashMap k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> NEHashMap k a -> a
foldr1 :: (a -> a -> a) -> NEHashMap k a -> a
$cfoldr1 :: forall k a. (a -> a -> a) -> NEHashMap k a -> a
foldl' :: (b -> a -> b) -> b -> NEHashMap k a -> b
$cfoldl' :: forall k b a. (b -> a -> b) -> b -> NEHashMap k a -> b
foldl :: (b -> a -> b) -> b -> NEHashMap k a -> b
$cfoldl :: forall k b a. (b -> a -> b) -> b -> NEHashMap k a -> b
foldr' :: (a -> b -> b) -> b -> NEHashMap k a -> b
$cfoldr' :: forall k a b. (a -> b -> b) -> b -> NEHashMap k a -> b
foldr :: (a -> b -> b) -> b -> NEHashMap k a -> b
$cfoldr :: forall k a b. (a -> b -> b) -> b -> NEHashMap k a -> b
foldMap' :: (a -> m) -> NEHashMap k a -> m
$cfoldMap' :: forall k m a. Monoid m => (a -> m) -> NEHashMap k a -> m
foldMap :: (a -> m) -> NEHashMap k a -> m
$cfoldMap :: forall k m a. Monoid m => (a -> m) -> NEHashMap k a -> m
fold :: NEHashMap k m -> m
$cfold :: forall k m. Monoid m => NEHashMap k m -> m
Foldable, Functor (NEHashMap k)
Foldable (NEHashMap k)
Functor (NEHashMap k)
-> Foldable (NEHashMap k)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> NEHashMap k a -> f (NEHashMap k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    NEHashMap k (f a) -> f (NEHashMap k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> NEHashMap k a -> m (NEHashMap k b))
-> (forall (m :: * -> *) a.
    Monad m =>
    NEHashMap k (m a) -> m (NEHashMap k a))
-> Traversable (NEHashMap k)
(a -> f b) -> NEHashMap k a -> f (NEHashMap k b)
forall k. Functor (NEHashMap k)
forall k. Foldable (NEHashMap k)
forall k (m :: * -> *) a.
Monad m =>
NEHashMap k (m a) -> m (NEHashMap k a)
forall k (f :: * -> *) a.
Applicative f =>
NEHashMap k (f a) -> f (NEHashMap k a)
forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NEHashMap k a -> m (NEHashMap k b)
forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NEHashMap k a -> f (NEHashMap k b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
NEHashMap k (m a) -> m (NEHashMap k a)
forall (f :: * -> *) a.
Applicative f =>
NEHashMap k (f a) -> f (NEHashMap k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NEHashMap k a -> m (NEHashMap k b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NEHashMap k a -> f (NEHashMap k b)
sequence :: NEHashMap k (m a) -> m (NEHashMap k a)
$csequence :: forall k (m :: * -> *) a.
Monad m =>
NEHashMap k (m a) -> m (NEHashMap k a)
mapM :: (a -> m b) -> NEHashMap k a -> m (NEHashMap k b)
$cmapM :: forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NEHashMap k a -> m (NEHashMap k b)
sequenceA :: NEHashMap k (f a) -> f (NEHashMap k a)
$csequenceA :: forall k (f :: * -> *) a.
Applicative f =>
NEHashMap k (f a) -> f (NEHashMap k a)
traverse :: (a -> f b) -> NEHashMap k a -> f (NEHashMap k b)
$ctraverse :: forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NEHashMap k a -> f (NEHashMap k b)
$cp2Traversable :: forall k. Foldable (NEHashMap k)
$cp1Traversable :: forall k. Functor (NEHashMap k)
Traversable)

-------------------------------------------------------------------------------

-- | Construct a non-empty map with a single element.
singleton :: Hashable k => k -> v -> NEHashMap k v
singleton :: k -> v -> NEHashMap k v
singleton k
k v
v = HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap (HashMap k v -> NEHashMap k v) -> HashMap k v -> NEHashMap k v
forall a b. (a -> b) -> a -> b
$ k -> v -> HashMap k v
forall k v. Hashable k => k -> v -> HashMap k v
M.singleton k
k v
v

-- | Construct a non-empty map with the supplied mappings.
-- Returns 'Nothing' if the provided 'HashMap' is empty.
fromHashMap :: HashMap k v -> Maybe (NEHashMap k v)
fromHashMap :: HashMap k v -> Maybe (NEHashMap k v)
fromHashMap HashMap k v
m
  | HashMap k v -> Bool
forall k v. HashMap k v -> Bool
M.null HashMap k v
m = Maybe (NEHashMap k v)
forall a. Maybe a
Nothing
  | Bool
otherwise = NEHashMap k v -> Maybe (NEHashMap k v)
forall a. a -> Maybe a
Just (NEHashMap k v -> Maybe (NEHashMap k v))
-> NEHashMap k v -> Maybe (NEHashMap k v)
forall a b. (a -> b) -> a -> b
$ HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap HashMap k v
m

-- | Construct a non-empty map with the supplied mappings as follows:
--
-- * if the provided list contains duplicate mappings, the later mappings take
--   precedence;
-- * if the provided list is empty, returns 'Nothing'.
fromList :: (Eq k, Hashable k) => [(k, v)] -> Maybe (NEHashMap k v)
fromList :: [(k, v)] -> Maybe (NEHashMap k v)
fromList [] = Maybe (NEHashMap k v)
forall a. Maybe a
Nothing
fromList [(k, v)]
v = NEHashMap k v -> Maybe (NEHashMap k v)
forall a. a -> Maybe a
Just (NEHashMap k v -> Maybe (NEHashMap k v))
-> NEHashMap k v -> Maybe (NEHashMap k v)
forall a b. (a -> b) -> a -> b
$ HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap (HashMap k v -> NEHashMap k v) -> HashMap k v -> NEHashMap k v
forall a b. (a -> b) -> a -> b
$ [(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList [(k, v)]
v

-- | A variant of 'fromList' that uses 'NonEmpty' inputs.
fromNonEmpty :: (Eq k, Hashable k) => NonEmpty (k, v) -> NEHashMap k v
fromNonEmpty :: NonEmpty (k, v) -> NEHashMap k v
fromNonEmpty ((k, v)
x NE.:| [(k, v)]
xs) = HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap ([(k, v)] -> HashMap k v
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ((k, v)
x (k, v) -> [(k, v)] -> [(k, v)]
forall a. a -> [a] -> [a]
: [(k, v)]
xs))

-- | Convert a non-empty map to a 'HashMap'.
toHashMap :: NEHashMap k v -> HashMap k v
toHashMap :: NEHashMap k v -> HashMap k v
toHashMap = NEHashMap k v -> HashMap k v
forall k v. NEHashMap k v -> HashMap k v
unNEHashMap

-- | Convert a non-empty map to a non-empty list of key/value pairs. The closed
-- operations of 'NEHashMap' guarantee that this operation won't fail.
toNonEmpty :: NEHashMap k v -> NonEmpty (k, v)
toNonEmpty :: NEHashMap k v -> NonEmpty (k, v)
toNonEmpty = [(k, v)] -> NonEmpty (k, v)
forall a. [a] -> NonEmpty a
NE.fromList ([(k, v)] -> NonEmpty (k, v))
-> (NEHashMap k v -> [(k, v)]) -> NEHashMap k v -> NonEmpty (k, v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
M.toList (HashMap k v -> [(k, v)])
-> (NEHashMap k v -> HashMap k v) -> NEHashMap k v -> [(k, v)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NEHashMap k v -> HashMap k v
forall k v. NEHashMap k v -> HashMap k v
unNEHashMap

-- | Convert a non-empty map to a list of key/value pairs.
toList :: NEHashMap k v -> [(k, v)]
toList :: NEHashMap k v -> [(k, v)]
toList = HashMap k v -> [(k, v)]
forall k v. HashMap k v -> [(k, v)]
M.toList (HashMap k v -> [(k, v)])
-> (NEHashMap k v -> HashMap k v) -> NEHashMap k v -> [(k, v)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NEHashMap k v -> HashMap k v
forall k v. NEHashMap k v -> HashMap k v
unNEHashMap

-------------------------------------------------------------------------------

-- | Return the value to which the specified key is mapped, or 'Nothing' if
-- this map contains no mapping for the key.
lookup :: (Eq k, Hashable k) => k -> NEHashMap k v -> Maybe v
lookup :: k -> NEHashMap k v -> Maybe v
lookup k
k (NEHashMap HashMap k v
m) = k -> HashMap k v -> Maybe v
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup k
k HashMap k v
m

-- | Return the value to which the specified key is mapped, or 'Nothing' if
-- this map contains no mapping for the key.
--
-- This is a flipped version of 'lookup'.
(!?) :: (Eq k, Hashable k) => NEHashMap k v -> k -> Maybe v
!? :: NEHashMap k v -> k -> Maybe v
(!?) = (k -> NEHashMap k v -> Maybe v) -> NEHashMap k v -> k -> Maybe v
forall a b c. (a -> b -> c) -> b -> a -> c
flip k -> NEHashMap k v -> Maybe v
forall k v. (Eq k, Hashable k) => k -> NEHashMap k v -> Maybe v
lookup

-- | Return a list of this map's keys.
keys :: NEHashMap k v -> [k]
keys :: NEHashMap k v -> [k]
keys = HashMap k v -> [k]
forall k v. HashMap k v -> [k]
M.keys (HashMap k v -> [k])
-> (NEHashMap k v -> HashMap k v) -> NEHashMap k v -> [k]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NEHashMap k v -> HashMap k v
forall k v. NEHashMap k v -> HashMap k v
unNEHashMap

-------------------------------------------------------------------------------

-- | The union of two maps.
--
-- If a key occurs in both maps, the left map @m1@ (first argument) will be
-- preferred.
union :: (Eq k, Hashable k) => NEHashMap k v -> NEHashMap k v -> NEHashMap k v
union :: NEHashMap k v -> NEHashMap k v -> NEHashMap k v
union (NEHashMap HashMap k v
m1) (NEHashMap HashMap k v
m2) = HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap (HashMap k v -> NEHashMap k v) -> HashMap k v -> NEHashMap k v
forall a b. (a -> b) -> a -> b
$ HashMap k v -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k v -> HashMap k v
M.union HashMap k v
m1 HashMap k v
m2

-- | The union of two maps using a given value-wise union function.
--
-- If a key occurs in both maps, the provided function (first argument) will be
-- used to compute the result.
unionWith :: (Eq k, Hashable k) => (v -> v -> v) -> NEHashMap k v -> NEHashMap k v -> NEHashMap k v
unionWith :: (v -> v -> v) -> NEHashMap k v -> NEHashMap k v -> NEHashMap k v
unionWith v -> v -> v
fun (NEHashMap HashMap k v
m1) (NEHashMap HashMap k v
m2) = HashMap k v -> NEHashMap k v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap (HashMap k v -> NEHashMap k v) -> HashMap k v -> NEHashMap k v
forall a b. (a -> b) -> a -> b
$ (v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
M.unionWith v -> v -> v
fun HashMap k v
m1 HashMap k v
m2

-------------------------------------------------------------------------------

-- | @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.
--
-- The size of the result may be smaller if f maps two or more distinct keys to
-- the same new key. In this case there is no guarantee which of the associated
-- values is chosen for the conflicting key.
mapKeys :: (Eq k2, Hashable k2) => (k1 -> k2) -> NEHashMap k1 v -> NEHashMap k2 v
mapKeys :: (k1 -> k2) -> NEHashMap k1 v -> NEHashMap k2 v
mapKeys k1 -> k2
fun (NEHashMap HashMap k1 v
m) = HashMap k2 v -> NEHashMap k2 v
forall k v. HashMap k v -> NEHashMap k v
NEHashMap (HashMap k2 v -> NEHashMap k2 v) -> HashMap k2 v -> NEHashMap k2 v
forall a b. (a -> b) -> a -> b
$ (k1 -> k2) -> HashMap k1 v -> HashMap k2 v
forall k2 k1 v.
(Eq k2, Hashable k2) =>
(k1 -> k2) -> HashMap k1 v -> HashMap k2 v
M.mapKeys k1 -> k2
fun HashMap k1 v
m

-------------------------------------------------------------------------------

-- | Determines whether the left-hand-side and the right-hand-side are inverses of each other.
--
-- More specifically, for two maps @A@ and @B@, 'isInverseOf' is satisfied when both of the
-- following are true:
-- 1. @∀ key ∈ A. A[key] ∈  B ∧ B[A[key]] == key@
-- 2. @∀ key ∈ B. B[key] ∈  A ∧ A[B[key]] == key@
isInverseOf ::
  (Eq k, Hashable k, Eq v, Hashable v) => NEHashMap k v -> NEHashMap v k -> Bool
NEHashMap k v
lhs isInverseOf :: NEHashMap k v -> NEHashMap v k -> Bool
`isInverseOf` NEHashMap v k
rhs = NEHashMap k v -> HashMap k v
forall k v. NEHashMap k v -> HashMap k v
toHashMap NEHashMap k v
lhs HashMap k v -> HashMap v k -> Bool
forall k v.
(Eq k, Hashable k, Eq v, Hashable v) =>
HashMap k v -> HashMap v k -> Bool
`Extended.isInverseOf` NEHashMap v k -> HashMap v k
forall k v. NEHashMap k v -> HashMap k v
toHashMap NEHashMap v k
rhs