{-# LANGUAGE CPP, PatternGuards #-}------------------------------------------------------------------------------- |-- Module : Data.HashMap-- Copyright : (c) Milan Straka 2010-- License : BSD-style-- Maintainer : fox@ucw.cz-- Stability : provisional-- Portability : portable---- Persistent 'HashMap', which is defined as---- @-- data 'HashMap' k v = 'Data.IntMap.IntMap' ('Data.Map.Map' k v)-- @---- is an 'Data.IntMap.IntMap' indexed by hash values of keys,-- containing a map @'Data.Map.Map' k v@ with keys of the same hash values.---- The interface of a 'HashMap' is a suitable subset of 'Data.IntMap.IntMap'.---- The complexity of operations is determined by the complexities of-- 'Data.IntMap.IntMap' and 'Data.Map.Map' operations. See the sources of-- 'HashMap' to see which operations from @containers@ package are used.-----------------------------------------------------------------------------moduleData.HashMap(HashMap-- * Operators,(!),(\\)-- * Query,null,size,member,notMember,lookup,findWithDefault-- * Construction,empty,singleton-- ** Insertion,insert,insertWith,insertWithKey,insertLookupWithKey-- ** Delete\/Update,delete,adjust,adjustWithKey,update,updateWithKey,updateLookupWithKey,alter-- * Combine-- ** Union,union,unionWith,unionWithKey,unions,unionsWith-- ** Difference,difference,differenceWith,differenceWithKey-- ** Intersection,intersection,intersectionWith,intersectionWithKey-- * Traversal-- ** Map,map,mapWithKey,mapAccum,mapAccumWithKey-- ** Fold,fold,foldWithKey-- * Conversion,elems,keys,keysSet,assocs-- ** Lists,toList,fromList,fromListWith,fromListWithKey-- * Filter,filter,filterWithKey,partition,partitionWithKey,mapMaybe,mapMaybeWithKey,mapEither,mapEitherWithKey-- * Submap,isSubmapOf,isSubmapOfBy,isProperSubmapOf,isProperSubmapOfBy)whereimportPreludehiding(lookup,map,filter,null)importControl.Applicative(Applicative(pure,(<*>)))importData.HashableimportData.Foldable(Foldable(foldMap))importData.List(foldl')importData.Monoid(Monoid(..))importData.Traversable(Traversable(traverse))importData.Typeable#if __GLASGOW_HASKELL__importText.ReadimportData.Data(Data(..),mkNoRepType)#endifimportqualifiedData.IntMapasIimportqualifiedData.MapasMimportqualifiedData.SetasS{--------------------------------------------------------------------
Operators
--------------------------------------------------------------------}-- | Find the value at a key.-- Calls 'error' when the element can not be found.(!)::(Hashablek,Ordk)=>HashMapka->k->am!k=caselookupkmofNothing->error"HashMap.(!): key not an element of the map"Justv->v-- | Same as 'difference'.(\\)::Ordk=>HashMapka->HashMapkb->HashMapkam1\\m2=differencem1m2{--------------------------------------------------------------------
Types
--------------------------------------------------------------------}dataSomekv=Only!kv|More!(M.Mapkv)deriving(Eq,Ord)-- | The abstract type of a @HashMap@. Its interface is a suitable-- subset of 'Data.IntMap.IntMap'.newtypeHashMapkv=HashMap(I.IntMap(Somekv))deriving(Eq,Ord)instanceFunctor(HashMapk)wherefmap=mapinstanceOrdk=>Monoid(HashMapka)wheremempty=emptymappend=unionmconcat=unionsinstanceFoldable(HashMapk)wherefoldMapf(HashMapm)=foldMapsome_foldmwheresome_fold(Only_x)=fxsome_fold(Mores)=foldMapfsinstanceTraversable(HashMapk)wheretraversef(HashMapm)=pureHashMap<*>traversesome_traversemwheresome_traverse(Onlykx)=pure(Onlyk)<*>fxsome_traverse(Mores)=pureMore<*>traversefsinstance(Showk,Showa)=>Show(HashMapka)whereshowsPrecdm=showParen(d>10)$showString"fromList ".shows(toListm)instance(Readk,Hashablek,Ordk,Reada)=>Read(HashMapka)where#ifdef __GLASGOW_HASKELL__readPrec=parens$prec10$doIdent"fromList"<-lexPxs<-readPrecreturn(fromListxs)readListPrec=readListPrecDefault#elsereadsPrecp=readParen(p>10)$\r->do("fromList",s)<-lexr(xs,t)<-readssreturn(fromListxs,t)#endif#include "Typeable.h"INSTANCE_TYPEABLE2(HashMap,hashMapTc,"HashMap")#if __GLASGOW_HASKELL__{--------------------------------------------------------------------
A Data instance
--------------------------------------------------------------------}-- This instance preserves data abstraction at the cost of inefficiency.-- We omit reflection services for the sake of data abstraction.instance(Datak,Hashablek,Ordk,Dataa)=>Data(HashMapka)wheregfoldlfzm=zfromList`f`(toListm)toConstr_=error"toConstr"gunfold__=error"gunfold"dataTypeOf_=mkNoRepType"Data.HashMap.HashMap"dataCast1f=gcast1f#endif{--------------------------------------------------------------------
Comparing elements
--------------------------------------------------------------------}-- For ByteStrings, doing compare is usually faster than doing (==),-- according to benchmarks. A Set is using compare naturally. We therefore-- define eq :: Ord a => a -> a -> Bool, which serves as (==).{-# INLINE eq #-}eq::Orda=>a->a->Booleqxy=x`compare`y==EQ{--------------------------------------------------------------------
Query
--------------------------------------------------------------------}-- | Is the map empty?null::HashMapka->Boolnull(HashMapm)=I.nullm-- | Number of elements in the map.size::HashMapka->Intsize(HashMapm)=I.fold((+).some_size)0mwheresome_size(Only__)=1some_size(Mores)=M.sizes-- | Is the key a member of the map?member::(Hashablek,Ordk)=>k->HashMapka->Boolmemberkm=caselookupkmofNothing->FalseJust_->True-- | Is the key not a member of the map?notMember::(Hashablek,Ordk)=>k->HashMapka->BoolnotMemberkm=not$memberkmsome_lookup::Ordk=>k->Someka->Maybeasome_lookupk(Onlyk'x)|k`eq`k'=Justx|otherwise=Nothingsome_lookupk(Mores)=M.lookupks-- | Lookup the value at a key in the map.lookup::(Hashablek,Ordk)=>k->HashMapka->Maybealookupk(HashMapm)=I.lookup(hashk)m>>=some_lookupk-- | The expression @('findWithDefault' def k map)@ returns the value at key-- @k@ or returns @def@ when the key is not an element of the map.findWithDefault::(Hashablek,Ordk)=>a->k->HashMapka->afindWithDefaultdefkm=caselookupkmofNothing->defJustx->x{--------------------------------------------------------------------
Construction
--------------------------------------------------------------------}-- | The empty map.empty::HashMapkaempty=HashMapI.empty-- | A map of one element.singleton::Hashablek=>k->a->HashMapkasingletonkx=HashMap$I.singleton(hashk)$(Onlykx){--------------------------------------------------------------------
Insert
--------------------------------------------------------------------}-- | Insert a new key\/value pair in the map. If the key is already present in-- the map, the associated value is replaced with the supplied value, i.e.-- 'insert' is equivalent to @'insertWith' 'const'@.insert::(Hashablek,Ordk)=>k->a->HashMapka->HashMapkainsertkx(HashMapm)=HashMap$I.insertWithsome_insert(hashk)(Onlykx)mwheresome_insert_(Onlyk'x')|k`eq`k'=Onlykx|otherwise=More$M.insertkx(M.singletonk'x')some_insert_(Mores)=More$M.insertkxs-- | Insert with a combining function. @'insertWith' f key value mp@ will-- insert the pair (key, value) into @mp@ if key does not exist in the map. If-- the key does exist, the function will insert @f new_value old_value@.insertWith::(Hashablek,Ordk)=>(a->a->a)->k->a->HashMapka->HashMapkainsertWithfkx(HashMapm)=HashMap$I.insertWithsome_insert_with(hashk)(Onlykx)mwheresome_insert_with_(Onlyk'x')|k`eq`k'=Onlyk(fxx')|otherwise=More$M.insertkx(M.singletonk'x')some_insert_with_(Mores)=More$M.insertWithfkxs-- | Insert with a combining function. @'insertWithKey' f key value mp@ will-- insert the pair (key, value) into @mp@ if key does not exist in the map. If-- the key does exist, the function will insert @f key new_value old_value@.insertWithKey::(Hashablek,Ordk)=>(k->a->a->a)->k->a->HashMapka->HashMapkainsertWithKeyfkx(HashMapm)=HashMap$I.insertWithsome_insert_with_key(hashk)(Onlykx)mwheresome_insert_with_key_(Onlyk'x')|k`eq`k'=Onlyk(fkxx')|otherwise=More$M.insertkx(M.singletonk'x')some_insert_with_key_(Mores)=More$M.insertWithKeyfkxs-- | The expression (@'insertLookupWithKey' f k x map@) is a pair where the-- first element is equal to (@'lookup' k map@) and the second element equal to-- (@'insertWithKey' f k x map@).insertLookupWithKey::(Hashablek,Ordk)=>(k->a->a->a)->k->a->HashMapka->(Maybea,HashMapka)insertLookupWithKeyfkx(HashMapm)=caseI.insertLookupWithKeysome_insert_with_key(hashk)(Onlykx)mof(found,m')->(found>>=some_lookupk,HashMapm')wheresome_insert_with_key__(Onlyk'x')|k`eq`k'=Onlyk(fkxx')|otherwise=More$M.insertkx(M.singletonk'x')some_insert_with_key__(Mores)=More$M.insertWithKeyfkxs{--------------------------------------------------------------------
Deletion
--------------------------------------------------------------------}some_norm::M.Mapkv->Maybe(Somekv)some_norms=caseM.sizesof0->Nothing1->caseM.findMinsof(k,x)->Just$Onlykx_->Just$More$ssome_norm'::M.Mapkv->Somekvsome_norm's=caseM.sizesof1->caseM.findMinsof(k,x)->Onlykx_->More$s-- | Delete a key and its value from the map. When the key is not-- a member of the map, the original map is returned.delete::(Hashablek,Ordk)=>k->HashMapka->HashMapkadeletek(HashMapm)=HashMap$I.updatesome_delete(hashk)mwheresome_deletev@(Onlyk'_)|k`eq`k'=Nothing|otherwise=Justvsome_delete(Moret)=some_norm$M.deletekt-- | Adjust a value at a specific key. When the key is not a member of the map,-- the original map is returned.adjust::(Hashablek,Ordk)=>(a->a)->k->HashMapka->HashMapkaadjustfk(HashMapm)=HashMap$I.adjustsome_adjust(hashk)mwheresome_adjustv@(Onlyk'x)|k`eq`k'=Onlyk(fx)|otherwise=vsome_adjust(Moret)=More$M.adjustfkt-- | Adjust a value at a specific key. When the key is not a member of the map,-- the original map is returned.adjustWithKey::(Hashablek,Ordk)=>(k->a->a)->k->HashMapka->HashMapkaadjustWithKeyfk(HashMapm)=HashMap$I.adjustsome_adjust_with_key(hashk)mwheresome_adjust_with_keyv@(Onlyk'x)|k`eq`k'=Onlyk(fkx)|otherwise=vsome_adjust_with_key(Moret)=More$M.adjustWithKeyfkt-- | The expression (@'update' f k map@) updates the value @x@ at @k@ (if it is-- in the map). If (@f x@) is 'Nothing', the element is deleted. If it is-- (@'Just' y@), the key @k@ is bound to the new value @y@.update::(Hashablek,Ordk)=>(a->Maybea)->k->HashMapka->HashMapkaupdatefk(HashMapm)=HashMap$I.updatesome_update(hashk)mwheresome_updatev@(Onlyk'x)|k`eq`k'=fx>>=return.Onlyk'|otherwise=Justvsome_update(Moret)=some_norm$M.updatefkt-- | The expression (@'update' f k map@) updates the value @x@ at @k@ (if it is-- in the map). If (@f k x@) is 'Nothing', the element is deleted. If it is-- (@'Just' y@), the key @k@ is bound to the new value @y@.updateWithKey::(Hashablek,Ordk)=>(k->a->Maybea)->k->HashMapka->HashMapkaupdateWithKeyfk(HashMapm)=HashMap$I.updatesome_update_with_key(hashk)mwheresome_update_with_keyv@(Onlyk'x)|k`eq`k'=fkx>>=return.Onlyk'|otherwise=Justvsome_update_with_key(Moret)=some_norm$M.updateWithKeyfkt-- | Lookup and update. The function returns original value, if it is updated.-- This is different behavior than 'Data.Map.updateLookupWithKey'. Returns the-- original key value if the map entry is deleted.updateLookupWithKey::(Hashablek,Ordk)=>(k->a->Maybea)->k->HashMapka->(Maybea,HashMapka)updateLookupWithKeyfk(HashMapm)=caseI.updateLookupWithKeysome_update_with_key(hashk)mof(found,m')->(found>>=some_lookupk,HashMapm')wheresome_update_with_key_v@(Onlyk'x)|k`eq`k'=fkx>>=return.Onlyk'|otherwise=Justvsome_update_with_key_(Moret)=some_norm$M.updateWithKeyfkt-- | The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence-- thereof. 'alter' can be used to insert, delete, or update a value in an-- 'HashMap'.alter::(Hashablek,Ordk)=>(Maybea->Maybea)->k->HashMapka->HashMapkaalterfk(HashMapm)=HashMap$I.altersome_alter(hashk)mwheresome_alterNothing=fNothing>>=return.Onlyksome_alter(Justv@(Onlyk'x))|k`eq`k'=f(Justx)>>=return.Onlyk'|otherwise=Justvsome_alter(Just(Moret))=some_norm$M.alterfkt{--------------------------------------------------------------------
Union
--------------------------------------------------------------------}-- | The union of a list of maps.unions::Ordk=>[HashMapka]->HashMapkaunionsxs=foldl'unionemptyxs-- | The union of a list of maps, with a combining operation.unionsWith::Ordk=>(a->a->a)->[HashMapka]->HashMapkaunionsWithfxs=foldl'(unionWithf)emptyxs-- | The (left-biased) union of two maps.-- It prefers the first map when duplicate keys are encountered,-- i.e. (@'union' == 'unionWith' 'const'@).union::Ordk=>HashMapka->HashMapka->HashMapkaunion(HashMapm1)(HashMapm2)=HashMap$I.unionWithsome_unionm1m2wheresome_unionv@(Onlykx)(Onlyly)|k`eq`l=v|otherwise=More(M.singletonkx`M.union`M.singletonly)some_union(Onlykx)(Moret)=More$M.singletonkx`M.union`tsome_union(Moret)(Onlykx)=More$t`M.union`M.singletonkxsome_union(Moret)(Moreu)=More$t`M.union`usome_union_with_key::Ordk=>(k->a->a->a)->Someka->Someka->Somekasome_union_with_keyf(Onlykx)(Onlyly)|k`eq`l=Onlyk(fkxy)|otherwise=More(M.unionWithKeyf(M.singletonkx)(M.singletonly))some_union_with_keyf(Onlykx)(Moret)=More$M.unionWithKeyf(M.singletonkx)tsome_union_with_keyf(Moret)(Onlykx)=More$M.unionWithKeyft(M.singletonkx)some_union_with_keyf(Moret)(Moreu)=More$M.unionWithKeyftu-- | The union with a combining function.unionWith::Ordk=>(a->a->a)->HashMapka->HashMapka->HashMapkaunionWithf(HashMapm1)(HashMapm2)=HashMap$I.unionWith(some_union_with_key$constf)m1m2-- | The union with a combining function.unionWithKey::Ordk=>(k->a->a->a)->HashMapka->HashMapka->HashMapkaunionWithKeyf(HashMapm1)(HashMapm2)=HashMap$I.unionWith(some_union_with_keyf)m1m2{--------------------------------------------------------------------
Difference
--------------------------------------------------------------------}-- | Difference between two maps (based on keys).difference::Ordk=>HashMapka->HashMapkb->HashMapkadifference(HashMapm1)(HashMapm2)=HashMap$I.differenceWithsome_diffm1m2wheresome_diffv@(Onlyk_)(Onlyl_)|k`eq`l=Nothing|otherwise=Justvsome_diffv@(Onlyk_)(Moret)|k`M.member`t=Nothing|otherwise=Justvsome_diff(Moret)(Onlyk_)=some_norm$M.deletektsome_diff(Moret)(Moreu)=some_norm$t`M.difference`usome_diff_with_key::Ordk=>(k->a->b->Maybea)->Someka->Somekb->Maybe(Someka)some_diff_with_keyfv@(Onlykx)(Onlyly)|k`eq`l=fkxy>>=return.Onlyk|otherwise=Justvsome_diff_with_keyf(Onlykx)(Moret)=some_norm$M.differenceWithKeyf(M.singletonkx)tsome_diff_with_keyf(Moret)(Onlykx)=some_norm$M.differenceWithKeyft(M.singletonkx)some_diff_with_keyf(Moret)(Moreu)=some_norm$M.differenceWithKeyftu-- | Difference with a combining function.differenceWith::Ordk=>(a->b->Maybea)->HashMapka->HashMapkb->HashMapkadifferenceWithf(HashMapm1)(HashMapm2)=HashMap$I.differenceWith(some_diff_with_key$constf)m1m2-- | Difference with a combining function. When two equal keys are-- encountered, the combining function is applied to the key and both values.-- If it returns 'Nothing', the element is discarded (proper set difference).-- If it returns (@'Just' y@), the element is updated with a new value @y@.differenceWithKey::Ordk=>(k->a->b->Maybea)->HashMapka->HashMapkb->HashMapkadifferenceWithKeyf(HashMapm1)(HashMapm2)=HashMap$I.differenceWith(some_diff_with_keyf)m1m2{--------------------------------------------------------------------
Intersection
--------------------------------------------------------------------}delete_empty::I.IntMap(Someka)->I.IntMap(Someka)delete_empty=I.filtersome_emptywheresome_empty(Only__)=Truesome_empty(Moret)=not$M.nullt-- | The (left-biased) intersection of two maps (based on keys).intersection::Ordk=>HashMapka->HashMapkb->HashMapkaintersection(HashMapm1)(HashMapm2)=HashMap$delete_empty$I.intersectionWithsome_intersectionm1m2wheresome_intersectionv@(Onlyk_)(Onlyl_)|k`eq`l=v|otherwise=More(M.empty)some_intersectionv@(Onlyk_)(Moret)|k`M.member`t=v|otherwise=More(M.empty)some_intersection(Moret)(Onlykx)=some_norm'$M.intersectiont(M.singletonkx)some_intersection(Moret)(Moreu)=some_norm'$M.intersectiontusome_intersection_with_key::Ordk=>(k->a->b->c)->Someka->Somekb->Somekcsome_intersection_with_keyf(Onlykx)(Onlyly)|k`eq`l=Onlyk(fkxy)|otherwise=More(M.empty)some_intersection_with_keyf(Onlykx)(Moret)=some_norm'$M.intersectionWithKeyf(M.singletonkx)tsome_intersection_with_keyf(Moret)(Onlykx)=some_norm'$M.intersectionWithKeyft(M.singletonkx)some_intersection_with_keyf(Moret)(Moreu)=some_norm'$M.intersectionWithKeyftu-- | The intersection with a combining function.intersectionWith::Ordk=>(a->b->c)->HashMapka->HashMapkb->HashMapkcintersectionWithf(HashMapm1)(HashMapm2)=HashMap$delete_empty$I.intersectionWith(some_intersection_with_key$constf)m1m2-- | The intersection with a combining function.intersectionWithKey::Ordk=>(k->a->b->c)->HashMapka->HashMapkb->HashMapkcintersectionWithKeyf(HashMapm1)(HashMapm2)=HashMap$delete_empty$I.intersectionWith(some_intersection_with_keyf)m1m2{--------------------------------------------------------------------
Submap
--------------------------------------------------------------------}-- | Is this a proper submap? (ie. a submap but not equal).isProperSubmapOf::(Ordk,Eqa)=>HashMapka->HashMapka->BoolisProperSubmapOfm1m2=isSubmapOfm1m2&&sizem1<sizem2-- | Is this a proper submap? (ie. a submap but not equal). The expression-- (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when @m1@ and @m2@ are not-- equal, all keys in @m1@ are in @m2@, and when @f@ returns 'True' when-- applied to their respective values.isProperSubmapOfBy::Ordk=>(a->b->Bool)->HashMapka->HashMapkb->BoolisProperSubmapOfByfm1m2=isSubmapOfByfm1m2&&sizem1<sizem2-- | Is this a submap?isSubmapOf::(Ordk,Eqa)=>HashMapka->HashMapka->BoolisSubmapOf(HashMapm1)(HashMapm2)=I.isSubmapOfBysome_isSubmapOfm1m2wheresome_isSubmapOf(Onlyk_)(Onlyl_)=k`eq`lsome_isSubmapOf(Onlyk_)(Moret)=k`M.member`tsome_isSubmapOf(More_)(Only__)=Falsesome_isSubmapOf(Moret)(Moreu)=t`M.isSubmapOf`u-- | The expression (@'isSubmapOfBy' f m1 m2@) returns 'True' if all keys in-- @m1@ are in @m2@, and when @f@ returns 'True' when applied to their-- respective values.isSubmapOfBy::Ordk=>(a->b->Bool)->HashMapka->HashMapkb->BoolisSubmapOfByf(HashMapm1)(HashMapm2)=I.isSubmapOfBysome_isSubmapOfBym1m2wheresome_isSubmapOfBy(Onlykx)(Onlyly)=k`eq`l&&x`f`ysome_isSubmapOfBy(Onlykx)(Moret)|Justy<-M.lookupkt=fxy|otherwise=Falsesome_isSubmapOfBy(More_)(Only__)=Falsesome_isSubmapOfBy(Moret)(Moreu)=M.isSubmapOfByftu{--------------------------------------------------------------------
Mapping
--------------------------------------------------------------------}-- | Map a function over all values in the map.map::(a->b)->HashMapka->HashMapkbmapf(HashMapm)=HashMap$I.mapsome_mapmwheresome_map(Onlykx)=Onlyk$fxsome_map(Moret)=More$M.mapft-- | Map a function over all values in the map.mapWithKey::(k->a->b)->HashMapka->HashMapkbmapWithKeyf(HashMapm)=HashMap$I.mapsome_map_with_keymwheresome_map_with_key(Onlykx)=Onlyk$fkxsome_map_with_key(Moret)=More$M.mapWithKeyft-- | The function @'mapAccum'@ threads an accumulating argument through the map-- in unspecified order of keys.mapAccum::(a->b->(a,c))->a->HashMapkb->(a,HashMapkc)mapAccumfa(HashMapm)=caseI.mapAccumsome_map_accumamof(acc,m')->(acc,HashMapm')wheresome_map_accumacc(Onlykx)=casefaccxof(acc',x')->(acc',Onlykx')some_map_accumacc(Moret)=caseM.mapAccumfacctof(acc',t')->(acc',Moret')-- | The function @'mapAccumWithKey'@ threads an accumulating argument through-- the map in unspecified order of keys.mapAccumWithKey::(a->k->b->(a,c))->a->HashMapkb->(a,HashMapkc)mapAccumWithKeyfa(HashMapm)=caseI.mapAccumsome_map_accum_with_keyamof(acc,m')->(acc,HashMapm')wheresome_map_accum_with_keyacc(Onlykx)=casefacckxof(acc',x')->(acc',Onlykx')some_map_accum_with_keyacc(Moret)=caseM.mapAccumWithKeyfacctof(acc',t')->(acc',Moret'){--------------------------------------------------------------------
Filter
--------------------------------------------------------------------}-- | Filter all values that satisfy some predicate.filter::Ordk=>(a->Bool)->HashMapka->HashMapkafilterp(HashMapm)=HashMap$I.mapMaybesome_filtermwheresome_filterv@(Only_x)|px=Justv|otherwise=Nothingsome_filter(Moret)=some_norm$M.filterpt-- | Filter all keys\/values that satisfy some predicate.filterWithKey::Ordk=>(k->a->Bool)->HashMapka->HashMapkafilterWithKeyp(HashMapm)=HashMap$I.mapMaybesome_filter_with_keymwheresome_filter_with_keyv@(Onlykx)|pkx=Justv|otherwise=Nothingsome_filter_with_key(Moret)=some_norm$M.filterWithKeypt-- | Partition the map according to some predicate. The first map contains all-- elements that satisfy the predicate, the second all elements that fail the-- predicate.partition::Ordk=>(a->Bool)->HashMapka->(HashMapka,HashMapka)partitionpm=(filterpm,filter(not.p)m)-- | Partition the map according to some predicate. The first map contains all-- elements that satisfy the predicate, the second all elements that fail the-- predicate.partitionWithKey::Ordk=>(k->a->Bool)->HashMapka->(HashMapka,HashMapka)partitionWithKeypm=(filterWithKeypm,filterWithKey(\k->not.pk)m)-- | Map values and collect the 'Just' results.mapMaybe::Ordk=>(a->Maybeb)->HashMapka->HashMapkbmapMaybef(HashMapm)=HashMap$I.mapMaybesome_map_maybemwheresome_map_maybe(Onlykx)=fx>>=return.Onlyksome_map_maybe(Moret)=some_norm$M.mapMaybeft-- | Map keys\/values and collect the 'Just' results.mapMaybeWithKey::Ordk=>(k->a->Maybeb)->HashMapka->HashMapkbmapMaybeWithKeyf(HashMapm)=HashMap$I.mapMaybesome_map_maybe_with_keymwheresome_map_maybe_with_key(Onlykx)=fkx>>=return.Onlyksome_map_maybe_with_key(Moret)=some_norm$M.mapMaybeWithKeyft-- | Map values and separate the 'Left' and 'Right' results.mapEither::Ordk=>(a->Eitherbc)->HashMapka->(HashMapkb,HashMapkc)mapEitherfm=(mapMaybe(maybe_left.f)m,mapMaybe(maybe_right.f)m)-- | Map keys\/values and separate the 'Left' and 'Right' results.mapEitherWithKey::Ordk=>(k->a->Eitherbc)->HashMapka->(HashMapkb,HashMapkc)mapEitherWithKeyfm=(mapMaybeWithKey(\ka->maybe_left(fka))m,mapMaybeWithKey(\ka->maybe_right(fka))m)-- Helper functions for this sectionmaybe_left::Eitherab->Maybeamaybe_left(Lefta)=Justamaybe_left(Right_)=Nothingmaybe_right::Eitherab->Maybebmaybe_right(Rightb)=Justbmaybe_right(Left_)=Nothing{--------------------------------------------------------------------
Fold
--------------------------------------------------------------------}-- | Fold the values in the map, such that @'fold' f z == 'Prelude.foldr'-- f z . 'elems'@.fold::(a->b->b)->b->HashMapka->bfoldfz(HashMapm)=I.foldsome_foldzmwheresome_fold(Only_x)y=fxysome_fold(Moret)y=M.foldfyt-- | Fold the keys and values in the map, such that @'foldWithKey' f z ==-- 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.foldWithKey::(k->a->b->b)->b->HashMapka->bfoldWithKeyfz(HashMapm)=I.foldsome_fold_with_keyzmwheresome_fold_with_key(Onlykx)y=fkxysome_fold_with_key(Moret)y=M.foldWithKeyfyt{--------------------------------------------------------------------
List variations
--------------------------------------------------------------------}-- | Return all elements of the map in arbitrary order of their keys.elems::HashMapka->[a]elems(HashMapm)=I.foldsome_append_elems[]mwheresome_append_elems(Only_x)acc=x:accsome_append_elems(Moret)acc=M.elemst++acc-- | Return all keys of the map in arbitrary order.keys::HashMapka->[k]keys(HashMapm)=I.foldsome_append_keys[]mwheresome_append_keys(Onlyk_)acc=k:accsome_append_keys(Moret)acc=M.keyst++acc-- | The set of all keys of the map.keysSet::Ordk=>HashMapka->S.SetkkeysSet(HashMapm)=I.fold(S.union.some_keys_set)S.emptymwheresome_keys_set(Onlyk_)=S.singletonksome_keys_set(Moret)=M.keysSett-- | Return all key\/value pairs in the map in arbitrary key order.assocs::HashMapka->[(k,a)]assocs=toList{--------------------------------------------------------------------
Lists
--------------------------------------------------------------------}-- | Convert the map to a list of key\/value pairs.toList::HashMapka->[(k,a)]toList(HashMapm)=I.foldsome_append[]mwheresome_append(Onlykx)acc=(k,x):accsome_append(Moret)acc=M.toListt++acc-- | Create a map from a list of key\/value pairs.fromList::(Hashablek,Ordk)=>[(k,a)]->HashMapkafromListxs=foldl'(\m(k,x)->insertkxm)emptyxs-- | Create a map from a list of key\/value pairs with a combining function.fromListWith::(Hashablek,Ordk)=>(a->a->a)->[(k,a)]->HashMapkafromListWithfxs=foldl'(\m(k,x)->insertWithfkxm)emptyxs-- | Build a map from a list of key\/value pairs with a combining function.fromListWithKey::(Hashablek,Ordk)=>(k->a->a->a)->[(k,a)]->HashMapkafromListWithKeyfxs=foldl'(\m(k,x)->insertWithKeyfkxm)emptyxs