refined-containers-0.1.2.0: Type-checked proof that a key exists in a container and can be safely indexed.
Safe HaskellNone
LanguageHaskell2010

Data.HashMap.Refined

Description

This module defines a way to prove that a key exists in a map, so that the key can be used to index into the map without using a Maybe, or manually handling the "impossible" case with error or other partial functions.

To do this, HashMap s k v has a type parameter s that identifies its set of keys, so that if another map has the same type parameter, you know that map has the same set of keys. There is Key s k, a type of keys that have been validated to belong to the set identified by s, and for which the operation of indexing into a HashMap s k v (only for the same s) can proceed without failure (see !). The type s itself has no internal structure, rather it is merely a skolem type variable (rank-2 polymorphism runST trick) introduced by Data.Reflection.

Like Data.HashMap.Lazy, functions in this module are strict in the keys but lazy in the values. The Data.HashMap.Strict.Refined module reuses the same HashMap type but provides functions that operate strictly on the values.

Warning

This module together with Data.HashMap.Lazy rely on Eq and Hashable instances being lawful: that == is an equivalence relation, and that hashWithSalt is defined on the quotient by this equivalence relation; at least for the subset of values that are actually encountered at runtime. If this assumption is violated, this module may not be able to uphold its invariants and may throw errors. In particular beware of NaN in Float and Double, and, if using hashable < 1.3, beware of 0 and -0.

Synopsis

Map type

data HashMap s k a Source #

A wrapper around a regular HashMap with a type parameter s identifying the set of keys present in the map.

A key of type k may not be present in the map, but a Key s k is guaranteed to be present (if the s parameters match). Thus the map is isomorphic to a (total) function Key s k -> a, which motivates many of the instances below.

A HashMap always knows its set of keys, so given HashMap s k a we can always derive KnownHashSet s k by pattern matching on the Dict returned by keysSet.

Instances

Instances details
Bifoldable (HashMap s) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

bifold :: Monoid m => HashMap s m m -> m #

bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> HashMap s a b -> m #

bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> HashMap s a b -> c #

bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> HashMap s a b -> c #

Eq2 (HashMap s) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftEq2 :: (a -> b -> Bool) -> (c -> d -> Bool) -> HashMap s a c -> HashMap s b d -> Bool #

Ord2 (HashMap s) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftCompare2 :: (a -> b -> Ordering) -> (c -> d -> Ordering) -> HashMap s a c -> HashMap s b d -> Ordering #

Show2 (HashMap s) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int -> HashMap s a b -> ShowS #

liftShowList2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> [HashMap s a b] -> ShowS #

(Hashable k, KnownHashSet s k) => Representable (HashMap s k) Source #

Witness isomorphism with functions from Key s k

Instance details

Defined in Data.HashMap.Common.Refined

Associated Types

type Rep (HashMap s k) 
Instance details

Defined in Data.HashMap.Common.Refined

type Rep (HashMap s k) = Key s k

Methods

tabulate :: (Rep (HashMap s k) -> a) -> HashMap s k a #

index :: HashMap s k a -> Rep (HashMap s k) -> a #

Eq k => Eq1 (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftEq :: (a -> b -> Bool) -> HashMap s k a -> HashMap s k b -> Bool #

Ord k => Ord1 (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftCompare :: (a -> b -> Ordering) -> HashMap s k a -> HashMap s k b -> Ordering #

Show k => Show1 (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> HashMap s k a -> ShowS #

liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [HashMap s k a] -> ShowS #

(Hashable k, KnownHashSet s k) => Distributive (HashMap s k) Source #

Similar to the instance for functions

Instance details

Defined in Data.HashMap.Common.Refined

Methods

distribute :: Functor f => f (HashMap s k a) -> HashMap s k (f a) #

collect :: Functor f => (a -> HashMap s k b) -> f a -> HashMap s k (f b) #

distributeM :: Monad m => m (HashMap s k a) -> HashMap s k (m a) #

collectM :: Monad m => (a -> HashMap s k b) -> m a -> HashMap s k (m b) #

(Hashable k, KnownHashSet s k) => Applicative (HashMap s k) Source #

Similar to the instance for functions -- zip corresponding keys. To use <*>/liftA2 without KnownHashSet see zipWith.

Instance details

Defined in Data.HashMap.Common.Refined

Methods

pure :: a -> HashMap s k a #

(<*>) :: HashMap s k (a -> b) -> HashMap s k a -> HashMap s k b #

liftA2 :: (a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c #

(*>) :: HashMap s k a -> HashMap s k b -> HashMap s k b #

(<*) :: HashMap s k a -> HashMap s k b -> HashMap s k a #

Functor (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

fmap :: (a -> b) -> HashMap s k a -> HashMap s k b #

(<$) :: a -> HashMap s k b -> HashMap s k a #

(Hashable k, KnownHashSet s k) => Monad (HashMap s k) Source #

Similar to the instance for functions. To use >>= without KnownHashSet see bind.

Instance details

Defined in Data.HashMap.Common.Refined

Methods

(>>=) :: HashMap s k a -> (a -> HashMap s k b) -> HashMap s k b #

(>>) :: HashMap s k a -> HashMap s k b -> HashMap s k b #

return :: a -> HashMap s k a #

Foldable (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

fold :: Monoid m => HashMap s k m -> m #

foldMap :: Monoid m => (a -> m) -> HashMap s k a -> m #

foldMap' :: Monoid m => (a -> m) -> HashMap s k a -> m #

foldr :: (a -> b -> b) -> b -> HashMap s k a -> b #

foldr' :: (a -> b -> b) -> b -> HashMap s k a -> b #

foldl :: (b -> a -> b) -> b -> HashMap s k a -> b #

foldl' :: (b -> a -> b) -> b -> HashMap s k a -> b #

foldr1 :: (a -> a -> a) -> HashMap s k a -> a #

foldl1 :: (a -> a -> a) -> HashMap s k a -> a #

toList :: HashMap s k a -> [a] #

null :: HashMap s k a -> Bool #

length :: HashMap s k a -> Int #

elem :: Eq a => a -> HashMap s k a -> Bool #

maximum :: Ord a => HashMap s k a -> a #

minimum :: Ord a => HashMap s k a -> a #

sum :: Num a => HashMap s k a -> a #

product :: Num a => HashMap s k a -> a #

Traversable (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

traverse :: Applicative f => (a -> f b) -> HashMap s k a -> f (HashMap s k b) #

sequenceA :: Applicative f => HashMap s k (f a) -> f (HashMap s k a) #

mapM :: Monad m => (a -> m b) -> HashMap s k a -> m (HashMap s k b) #

sequence :: Monad m => HashMap s k (m a) -> m (HashMap s k a) #

FoldableWithIndex (Key s k) (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

ifoldMap :: Monoid m => (Key s k -> a -> m) -> HashMap s k a -> m #

ifoldMap' :: Monoid m => (Key s k -> a -> m) -> HashMap s k a -> m #

ifoldr :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b #

ifoldl :: (Key s k -> b -> a -> b) -> b -> HashMap s k a -> b #

ifoldr' :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b #

ifoldl' :: (Key s k -> b -> a -> b) -> b -> HashMap s k a -> b #

FunctorWithIndex (Key s k) (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

imap :: (Key s k -> a -> b) -> HashMap s k a -> HashMap s k b #

TraversableWithIndex (Key s k) (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

itraverse :: Applicative f => (Key s k -> a -> f b) -> HashMap s k a -> f (HashMap s k b) #

(Hashable k, KnownHashSet s k) => MonadReader (Key s k) (HashMap s k) Source #

Similar to the instance for functions. See also backpermuteKeys.

Instance details

Defined in Data.HashMap.Common.Refined

Methods

ask :: HashMap s k (Key s k) #

local :: (Key s k -> Key s k) -> HashMap s k a -> HashMap s k a #

reader :: (Key s k -> a) -> HashMap s k a #

(NFData k, NFData a) => NFData (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

rnf :: HashMap s k a -> () #

(Hashable k, KnownHashSet s k, Monoid a) => Monoid (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

mempty :: HashMap s k a #

mappend :: HashMap s k a -> HashMap s k a -> HashMap s k a #

mconcat :: [HashMap s k a] -> HashMap s k a #

(Hashable k, Semigroup a) => Semigroup (HashMap s k a) Source #

Append the values at the corresponding keys

Instance details

Defined in Data.HashMap.Common.Refined

Methods

(<>) :: HashMap s k a -> HashMap s k a -> HashMap s k a #

sconcat :: NonEmpty (HashMap s k a) -> HashMap s k a #

stimes :: Integral b => b -> HashMap s k a -> HashMap s k a #

(Show k, Show a) => Show (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

showsPrec :: Int -> HashMap s k a -> ShowS #

show :: HashMap s k a -> String #

showList :: [HashMap s k a] -> ShowS #

(Eq k, Eq a) => Eq (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

(==) :: HashMap s k a -> HashMap s k a -> Bool #

(/=) :: HashMap s k a -> HashMap s k a -> Bool #

(Ord k, Ord a) => Ord (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

compare :: HashMap s k a -> HashMap s k a -> Ordering #

(<) :: HashMap s k a -> HashMap s k a -> Bool #

(<=) :: HashMap s k a -> HashMap s k a -> Bool #

(>) :: HashMap s k a -> HashMap s k a -> Bool #

(>=) :: HashMap s k a -> HashMap s k a -> Bool #

max :: HashMap s k a -> HashMap s k a -> HashMap s k a #

min :: HashMap s k a -> HashMap s k a -> HashMap s k a #

(Hashable k, Hashable a) => Hashable (HashMap s k a) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

Methods

hashWithSalt :: Int -> HashMap s k a -> Int #

hash :: HashMap s k a -> Int #

type Rep (HashMap s k) Source # 
Instance details

Defined in Data.HashMap.Common.Refined

type Rep (HashMap s k) = Key s k

type Key s = Refined (InSet 'Hashed s) Source #

Key s k is a key of type k that has been verified to be an element of the set s, and thus verified to be present in all HashMap s k maps.

Thus, Key s k is a "refinement" type of k, and this library integrates with an implementation of refimenement types in Refined, so the machinery from there can be used to manipulate Keys (however see revealPredicate).

The underlying k value can be obtained with unrefine. A k can be validated into an Key s k with member.

Existentials and common proofs

data SomeHashMap k a where Source #

An existential wrapper for a HashMap with an as-yet-unknown set of keys. Pattern maching on it gives you a way to refer to the set (the parameter s), e.g.

case fromHashMap ... of
  SomeHashMap @s m -> doSomethingWith @s

case fromHashMap ... of
  SomeHashMap (m :: HashMap s k a) -> doSomethingWith @s

Constructors

SomeHashMap :: forall s k a. !(HashMap s k a) -> SomeHashMap k a 

withHashMap :: SomeHashMap k a -> (forall s. HashMap s k a -> r) -> r Source #

Apply a map with an unknown set of keys to a continuation that can accept a map with any set of keys. This gives you a way to refer to the set (the parameter s), e.g.:

withHashMap (fromHashMap ...
  $ \(m :: HashMap s k a) -> doSomethingWith @s

data SomeHashMapWith (p :: Type -> Type) k a where Source #

An existential wrapper for a HashMap with an as-yet-unknown set of keys, together with a proof of some fact p about the set. Pattern matching on it gives you a way to refer to the set (the parameter s). Functions that change the set of keys in a map will return the map in this way, together with a proof that somehow relates the keys set to the function's inputs.

Constructors

SomeHashMapWith :: forall s k a (p :: Type -> Type). !(HashMap s k a) -> !(p s) -> SomeHashMapWith p k a 

withHashMapWith :: forall k a r p. SomeHashMapWith p k a -> (forall s. HashMap s k a -> p s -> r) -> r Source #

Apply a map with proof for an unknown set of keys to a continuation that can accept a map with any set of keys satisfying the proof. This gives you a way to refer to the set (the parameter s).

data Some2HashMapWith (p :: Type -> Type -> Type) k a b where Source #

An existential wrapper for a pair of maps with as-yet-unknown sets of keys, together with a proof of some fact p relating them.

Constructors

Some2HashMapWith :: forall s t k a b (p :: Type -> Type -> Type). !(HashMap s k a) -> !(HashMap t k b) -> !(p s t) -> Some2HashMapWith p k a b 

with2HashMapWith :: forall k a b r p. Some2HashMapWith p k a b -> (forall s t. HashMap s k a -> HashMap t k b -> p s t -> r) -> r Source #

Apply a pair of maps with proof for unknown sets of keys to a continuation that can accept any pair of maps with any sets of keys satisfying the proof. This gives you a way to refer to the sets (the parameters s and t).

newtype SupersetProof (f :: Flavor) s r Source #

Proof that s is a superset of the set r.

Constructors

SupersetProof (InSet f r :-> InSet f s)

\(r \subseteq s\)

newtype EmptyProof (f :: Flavor) r Source #

Proof that the set r is empty.

Constructors

EmptyProof (forall s. InSet f r :-> InSet f s)

\(\forall s, r \subseteq s\), which is equivalent to \(r \subseteq \varnothing\)

Construction

singleton :: Hashable k => k -> a -> SomeHashMapWith (SingletonProof 'Hashed k) k a Source #

Create a map with a single key-value pair, and return a proof that the key is in the resulting map.

newtype SingletonProof (f :: Flavor) a r Source #

Proof that r contains an element of type a.

Constructors

SingletonProof (Refined (InSet f r) a)

The element that is guaranteed to be in r

fromSet :: KnownHashSet s k => (Key s k -> a) -> HashMap s k a Source #

Create a map from a set of keys, and a function that for each key computes the corresponding value.

fromHashMap :: HashMap k a -> SomeHashMap k a Source #

Construct a map from a regular HashMap.

verifyHashMap :: forall s k a. (Hashable k, KnownHashSet s k) => HashMap k a -> Maybe (HashMap s k a) Source #

Given a set of keys s known ahead of time, verify whether a regular HashMap has exactly that set of keys.

fromTraversable :: (Traversable t, Hashable k) => t (k, a) -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a Source #

Create a map from an arbitrary traversable of key-value pairs. If a key is repeated, the retained value is the last one in traversal order. If you're looking for fromList, this is the function you want.

fromTraversableWith :: (Traversable t, Hashable k) => (a -> a -> a) -> t (k, a) -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a Source #

Create a map from an arbitrary traversable of key-value pairs, with a function for combining values for repeated keys. The function is called as if by foldl1, but flipped:

fromTraversableWith f [(k, x1), (k, x2), (k, x3)]
  = singleton k (f x3 (f x2 x1))

fromTraversableWithKey :: (Traversable t, Hashable k) => (k -> a -> a -> a) -> t (k, a) -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a Source #

Create a map from an arbitrary traversable of key-value pairs. Like fromTraversableWith, but the combining function has access to the key.

newtype FromTraversableProof (f :: Flavor) (t :: Type -> Type) a r Source #

Proof that elements of t a are contained in r.

Constructors

FromTraversableProof (t (Refined (InSet f r) a))

The original traversable, with all elements refined with a guarantee of being in r

Insertion

insert :: forall s k a. Hashable k => k -> a -> HashMap s k a -> SomeHashMapWith (InsertProof 'Hashed k s) k a Source #

Insert a key-value pair into the map to obtain a potentially larger map, guaranteed to contain the given key. If the key was already present, the associated value is replaced with the supplied value.

insertWith :: forall s k a. Hashable k => (a -> a -> a) -> k -> a -> HashMap s k a -> SomeHashMapWith (InsertProof 'Hashed k s) k a Source #

Insert a key-value pair into the map to obtain a potentially larger map, guaranteed to contain the given key. If the key was already present, the supplied function is used to combine the new value with the old (in that order).

insertWithKey :: forall s k a. Hashable k => (Key s k -> a -> a -> a) -> k -> a -> HashMap s k a -> SomeHashMapWith (InsertProof 'Hashed k s) k a Source #

Insert a key-value pair into the map to obtain a potentially larger map, guaranteed to contain the given key. Like insertWith, but the combining function has access to the key, which is guaranteed to be in the old map.

data InsertProof (f :: Flavor) a s r Source #

Proof that r is s with a inserted.

Constructors

InsertProof 

Fields

  • (Refined (InSet f r) a)

    The element that was inserted and is guaranteed to be in r.

  • (InSet f s :-> InSet f r)

    \(s \subseteq r \)

reinsert :: forall s k a. Hashable k => Key s k -> a -> HashMap s k a -> HashMap s k a Source #

Overwrite a key-value pair that is known to already be in the map. The set of keys remains the same.

insertLookupWithKey :: forall s k a. Hashable k => (Key s k -> a -> a -> a) -> k -> a -> HashMap s k a -> (Maybe (Key s k, a), SomeHashMapWith (InsertProof 'Hashed k s) k a) Source #

Insert a key-value pair into the map using a combining function, and if the key was already present, the old value is returned along with the proof that the key was present.

Deletion/Update

delete :: forall s k a. Hashable k => k -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

Delete a key and its value from the map if present, returning a potentially smaller map.

adjust' :: forall s k a. Hashable k => (a -> a) -> k -> HashMap s k a -> HashMap s k a Source #

If the given key is in the map, update the value at that key using the given function. In any case, the set of keys remains the same.

adjust :: forall s k a. Hashable k => (a -> a) -> Key s k -> HashMap s k a -> HashMap s k a Source #

Update the value at a specific key known the be in the map using the given function. The set of keys remains the same.

reinsert k v = 'adjust (const v) k'

adjustWithKey :: forall s k a. Hashable k => (Key s k -> a -> a) -> k -> HashMap s k a -> HashMap s k a Source #

If the given key is in the map, update the associated value using the given function with a proof that the key was in the map; otherwise return the map unchanged. In any case the set of keys remains the same.

update' :: forall s k a. Hashable k => (a -> Maybe a) -> k -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

If a key is present in the map, update its value or delete it using the given function, returning a potentially smaller map.

update :: forall s k a. Hashable k => (a -> Maybe a) -> Key s k -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

Update or delete a key known to be in the map using the given function, returning a potentially smaller map.

updateWithKey :: forall s k a. Hashable k => (Key s k -> a -> Maybe a) -> k -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

If a key is present in the map, update its value or delete it using the given function with a proof that the key was in the map, returning a potentially smaller map.

updateLookupWithKey :: forall s k a. Hashable k => (Key s k -> a -> Maybe a) -> k -> HashMap s k a -> (Maybe (Key s k, a), SomeHashMapWith (SupersetProof 'Hashed s) k a) Source #

If the given key is in the map, update or delete it using the given function with a proof that the key was in the map; otherwise the map is unchanged. Alongside return the new value if it was updated, or the old value if it was deleted, and a proof that the key was in the map.

Query

lookup :: forall s k a. Hashable k => k -> HashMap s k a -> Maybe (Key s k, a) Source #

If the key is in the map, return the proof of this, and the associated value; otherwise return Nothing.

(!) :: forall s k a. Hashable k => HashMap s k a -> Key s k -> a Source #

Given a key that is proven to be in the map, return the associated value.

Unlike ! from Data.HashMap.Lazy, this function is total, as it is impossible to obtain a Key s k for a key that is not in the map HashMap s k a.

member :: forall s k a. Hashable k => k -> HashMap s k a -> Maybe (Key s k) Source #

If a key is in the map, return the proof that it is.

null :: HashMap s k a -> Maybe (EmptyProof 'Hashed s) Source #

If a map is empty, return a proof that it is.

isSubmapOfBy :: forall s t k a b. Hashable k => (a -> b -> Bool) -> HashMap s k a -> HashMap t k b -> Maybe (SubsetProof 'Hashed s t) Source #

If all keys of the first map are also present in the second map, and the given function returns True for their associated values, return a proof that the keys form a subset.

newtype SubsetProof (f :: Flavor) s r Source #

Proof that s is a subset of the set r.

Constructors

SubsetProof (InSet f s :-> InSet f r)

\(s \subseteq r\)

disjoint :: forall s t k a b. Hashable k => HashMap s k a -> HashMap t k b -> Maybe (DisjointProof 'Hashed s t) Source #

If two maps are disjoint (i.e. their intersection is empty), return a proof of that.

newtype DisjointProof (f :: Flavor) s r Source #

Proof that s and r are disjoint.

Constructors

DisjointProof (forall t. (InSet f t :-> InSet f s) -> (InSet f t :-> InSet f r) -> forall u x. Refined (InSet f t) x -> Refined (InSet f u) x)

\(\forall t,(t\subseteq s)\land(t\subseteq r)\implies\forall u,t\subseteq u\), which is equivalent to \(s \cap r \subseteq \varnothing\)

Combine

zipWith :: forall s k a b c. Hashable k => (a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c Source #

Given two maps proven to have the same keys, for each key apply the function to the associated values, to obtain a new map with the same keys.

zipWithKey :: forall s k a b c. Hashable k => (Key s k -> a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c Source #

Given two maps proven to have the same keys, for each key apply the function to the associated values and the key, to obtain a new map with the same keys.

bind :: forall s k a b. Hashable k => HashMap s k a -> (a -> HashMap s k b) -> HashMap s k b Source #

bind m f is a map that for each key k :: Key s k, contains the value f (m ! k) ! k, similar to >>= for functions.

union :: forall s t k a. Hashable k => HashMap s k a -> HashMap t k a -> SomeHashMapWith (UnionProof 'Hashed s t) k a Source #

Return the union of two maps. For keys that exist in both maps, the value is taken from the first map.

union = unionWith const

unionWith :: forall s t k a. Hashable k => (a -> a -> a) -> HashMap s k a -> HashMap t k a -> SomeHashMapWith (UnionProof 'Hashed s t) k a Source #

Return the union of two maps, with a given combining function for keys that exist in both maps simultaneously.

unionWithKey :: forall s t k a. Hashable k => (Refined (InSet 'Hashed s && InSet 'Hashed t) k -> a -> a -> a) -> HashMap s k a -> HashMap t k a -> SomeHashMapWith (UnionProof 'Hashed s t) k a Source #

Return the union of two maps, with a given combining function for keys that exist in both maps simultaneously.

You can use andLeft and andRight to obtain Key s k and Key t k respectively.

data UnionProof (f :: Flavor) s t r Source #

Proof that unioning s and t gives r.

Constructors

UnionProof 

Fields

difference :: forall s t k a b. Hashable k => HashMap s k a -> HashMap t k b -> SomeHashMapWith (DifferenceProof 'Hashed s t) k a Source #

Remove the keys that appear in the second map from the first map.

data DifferenceProof (f :: Flavor) s t r Source #

Proof that if from s you subtract t, then you get r.

Constructors

DifferenceProof 

Fields

differenceWith :: forall s t k a b. Hashable k => (a -> b -> Maybe a) -> HashMap s k a -> HashMap t k b -> SomeHashMapWith (PartialDifferenceProof 'Hashed s t) k a Source #

Return the first map, but for keys that appear in both maps, the given function decides whether the key is removed.

differenceWithKey :: forall s t k a b. Hashable k => (Refined (InSet 'Hashed s && InSet 'Hashed t) k -> a -> b -> Maybe a) -> HashMap s k a -> HashMap t k b -> SomeHashMapWith (PartialDifferenceProof 'Hashed s t) k a Source #

Return the first map, but for keys that appear in both maps, the given function decides whether the key is removed.

You can use andLeft and andRight to obtain Key s k and Key t k respectively.

data PartialDifferenceProof (f :: Flavor) s t r Source #

Proof that r is obtained by removing some of t's elements from s.

Constructors

PartialDifferenceProof 

Fields

intersection :: forall s t k a b. Hashable k => HashMap s k a -> HashMap t k b -> SomeHashMapWith (IntersectionProof 'Hashed s t) k a Source #

Return the intersection of two maps, taking values from the first map.

intersection = intersectionWith const

intersectionWith :: forall s t k a b c. Hashable k => (a -> b -> c) -> HashMap s k a -> HashMap t k b -> SomeHashMapWith (IntersectionProof 'Hashed s t) k c Source #

Return the intersection of two maps with the given combining function.

intersectionWithKey :: forall s t k a b c. Hashable k => (Refined (InSet 'Hashed s && InSet 'Hashed t) k -> a -> b -> c) -> HashMap s k a -> HashMap t k b -> SomeHashMapWith (IntersectionProof 'Hashed s t) k c Source #

Return the intersection of two maps with the given combining function.

You can use andLeft and andRight to obtain Key s k and Key t k respectively.

data IntersectionProof (f :: Flavor) s t r Source #

Proof that intersecting s and t gives r.

Constructors

IntersectionProof 

Fields

Traversal

map :: forall s k a b. (a -> b) -> HashMap s k a -> HashMap s k b Source #

Apply a function to all values in a map. The set of keys remains the same.

mapWithKey :: (Key s k -> a -> b) -> HashMap s k a -> HashMap s k b Source #

Apply a function to all values in a map, together with their corresponding keys, that are proven to be in the map. The set of keys remains the same.

traverseWithKey :: forall s f k a b. Applicative f => (Key s k -> a -> f b) -> HashMap s k a -> f (HashMap s k b) Source #

Map an Applicative transformation with access to each value's corresponding key and a proof that it is in the map. The set of keys remains unchanged.

mapAccumLWithKey :: forall s k a b c. (a -> Key s k -> b -> (a, c)) -> a -> HashMap s k b -> (a, HashMap s k c) Source #

Thread an accumularing argument through the map in ascending order of hashes.

mapAccumRWithKey :: forall s k a b c. (a -> Key s k -> b -> (a, c)) -> a -> HashMap s k b -> (a, HashMap s k c) Source #

Thread an accumularing argument through the map in descending order of hashes.

mapKeys :: forall s k1 k2 a. Hashable k2 => (Key s k1 -> k2) -> HashMap s k1 a -> SomeHashMapWith (MapProof 'Hashed s k1 k2) k2 a Source #

mapKeys f m applies f to each key of m and collects the results into a new map. For keys that were mapped to the same new key, the value is picked in an unspecified way.

mapKeysWith :: forall s k1 k2 a. Hashable k2 => (a -> a -> a) -> (Key s k1 -> k2) -> HashMap s k1 a -> SomeHashMapWith (MapProof 'Hashed s k1 k2) k2 a Source #

mapKeysWith c f m applies f to each key of m and collects the results into a new map. For keys that were mapped to the same new key, c acts as the combining function for corresponding values.

data MapProof (f :: Flavor) s a b r Source #

Proof that r is the direct image of s under some mapping f :: a -> b.

Constructors

MapProof 

Fields

backpermuteKeys :: forall s1 s2 k1 k2 a. (Hashable k1, KnownHashSet s2 k2) => (Key s2 k2 -> Key s1 k1) -> HashMap s1 k1 a -> HashMap s2 k2 a Source #

Apply the inverse image of the given function to the keys of the given map, so that for all k :: Key s2 k2,c backpermuteKeys f m ! k = m ! f k.

If maps are identified with functions, this computes the composition.

Folds

foldMapWithKey :: forall s k a m. Monoid m => (Key s k -> a -> m) -> HashMap s k a -> m Source #

Map each key-value pair of a map into a monoid (with proof that the key was in the map), and combine the results using <>.

foldrWithKey :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b Source #

Right associative fold with a lazy accumulator.

foldlWithKey :: forall s k a b. (b -> Key s k -> a -> b) -> b -> HashMap s k a -> b Source #

Left associative fold with a lazy accumulator.

foldrWithKey' :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b Source #

Right associative fold with a strict accumulator.

foldlWithKey' :: forall s k a b. (b -> Key s k -> a -> b) -> b -> HashMap s k a -> b Source #

Left associative fold with a strict accumulator.

Conversion

toMap :: HashMap s k a -> HashMap k a Source #

Convert to a regular HashMap, forgetting its set of keys.

keysSet :: HashMap s k a -> HashSet s k Source #

Return the set of keys in the map, with the contents of the set still tracked by the s parameter. See Data.HashSet.Refined.

toList :: HashMap s k a -> [(Key s k, a)] Source #

Convert to a list of key-value pairs.

Filter

restrictKeys :: forall s t k a. (Hashable k, KnownHashSet t k) => HashMap s k a -> SomeHashMapWith (IntersectionProof 'Hashed s t) k a Source #

Restrict a map to only those keys that are elements of t.

withoutKeys :: forall s t k a. (Hashable k, KnownHashSet t k) => HashMap s k a -> SomeHashMapWith (DifferenceProof 'Hashed s t) k a Source #

Remove all keys that are elements of t from the map.

filter :: forall s k a. (a -> Bool) -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

Retain only the values that satisfy the predicate, returning a potentially smaller map.

filterKeys :: (Key s k -> Bool) -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

Retain only the keys that satisfy the predicate, returning a potentially smaller map.

filterWithKey :: (Key s k -> a -> Bool) -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k a Source #

Retain only the key-value pairs that satisfy the predicate, returning a potentially smaller map.

partition :: forall s k a. Hashable k => (a -> Bool) -> HashMap s k a -> Some2HashMapWith (PartitionProof 'Hashed s k) k a a Source #

Partition a map into two disjoint submaps: those whose key-value pairs satisfy the predicate, and those whose don't.

partitionWithKey :: forall s k a. Hashable k => (Key s k -> a -> Bool) -> HashMap s k a -> Some2HashMapWith (PartitionProof 'Hashed s k) k a a Source #

Partition a map into two disjoint submaps: those whose key-value pairs satisfy the predicate, and those whose don't.

data PartitionProof (f :: Flavor) s a r q Source #

Proof that s is the union of disjoint subsets r and q, together with a procedure that decides which of the two an element belongs to.

Constructors

PartitionProof 

Fields

mapMaybe :: forall s k a b. (a -> Maybe b) -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k b Source #

Apply a function to all values in a map and collect only the Just results, returning a potentially smaller map.

mapMaybeWithKey :: (Key s k -> a -> Maybe b) -> HashMap s k a -> SomeHashMapWith (SupersetProof 'Hashed s) k b Source #

Apply a function to all values in a map, together with their corresponding keys, and collect only the Just results, returning a potentially smaller map.

mapEither :: forall s k a b c. Hashable k => (a -> Either b c) -> HashMap s k a -> Some2HashMapWith (PartitionProof 'Hashed s k) k b c Source #

Apply a function to all values in a map and collect the Left and Right results into separate (disjoint) maps.

mapEitherWithKey :: forall s k a b c. Hashable k => (Key s k -> a -> Either b c) -> HashMap s k a -> Some2HashMapWith (PartitionProof 'Hashed s k) k b c Source #

Apply a function to all values in a map, together with their corresponding keys, and collect the Left and Right results into separate (disjoint) maps.

Casts

castKey :: (forall x. Key s x -> Key t x) -> (forall x. Key t x -> Key s x) -> Coercion (Key s k) (Key t k) Source #

If elements of s can be weakened to elements of t and vice versa, then s and t actually stand for the same set and Key s can be safely interconverted with Key t.

The requirement that the weakenings are natural transformations ensures that they don't actually alter the keys. To build these you can compose :->'s from proofs returned by functions in this module, or Refined functions like andLeft or leftOr.

cast :: (forall x. Coercion (Key s x) (Key t x)) -> Coercion (HashMap s k) (HashMap t k) Source #

If keys can be interconverted (e.g. as proved by castKey), then the maps can be interconverted too. For example, zipWithKey can be implemented via intersectionWithKey by proving that the set of keys remains unchanged:

zipWithKey
  :: forall s k a b c. Hashable k
  => (Key s k -> a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c
zipWithKey f m1 m2
  | SomeHashMapWith @r m proof <- intersectionWithKey (f . andLeft) m1 m2
  , IntersectionProof p1 p2 <- proof
  , ( Coercion :: Coercion (HashMap r k c) (HashMap s k c))
    <- app $ cast $ castKey (andLeft . p1) (p2 id id)
  = coerce m
  where
    app :: Coercion f g -> Coercion (f x) (g x)
    app Coercion = Coercion

castFlavor :: forall (f :: Flavor) (g :: Flavor) s a. Coercion (Refined (InSet f s) a) (Refined (InSet g s) a) Source #

This function can be used to freely convert between Element and Key types of various flavors (Regular, Int, Hashed), corresponding to the different implementations of sets and maps.