-- File created: 2008-11-12 14:16:48{-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances
, FlexibleContexts, UndecidableInstances #-}#include "exports.h"-- | The base implementation of a Patricia trie representing a map with list-- keys, generalized over any type of map from element values to tries.---- Worst-case complexities are given in terms of @n@, @m@, and @k@. @n@ refers-- to the number of keys in the map and @m@ to their maximum length. @k@ refers-- to the length of a key given to the function, not any property of the map.---- In addition, the trie's branching factor plays a part in almost every-- operation, but the complexity depends on the underlying 'Map'. Thus, for-- instance, 'member' is actually @O(m f(b))@ where @f(b)@ is the complexity of-- a lookup operation on the 'Map' used. This complexity depends on the-- underlying operation, which is not part of the specification of the visible-- function. Thus it could change whilst affecting the complexity only for-- certain Map types: hence this \"b factor\" is not shown explicitly.---- Disclaimer: the complexities have not been proven.---- Strict versions of functions are provided for those who want to be certain-- that their 'TrieMap' doesn't contain values consisting of unevaluated-- thunks. Note, however, that they do not evaluate the whole trie strictly,-- only the values. And only to one level of depth: for instance, 'alter'' does-- not 'seq' the value within the 'Maybe', only the 'Maybe' itself. The user-- should add the strictness in such cases himself, if he so wishes.---- Many functions come in both ordinary and @WithKey@ forms, where the former-- takes a function of type @a -> b@ and the latter of type @[k] -> a -> b@,-- where @[k]@ is the key associated with the value @a@. For most of these-- functions, there is additional overhead involved in keeping track of the-- key: don't use the latter form of the function unless you need it.moduleData.ListTrie.Patricia.Map(MAP_EXPORTS)whereimportControl.Applicative((<*>),(<$>))importControl.Arrow((***),second)importqualifiedData.DListasDLimportData.Either(partitionEithers)importData.Function(on)importqualifiedData.FoldableasFimportqualifiedData.MaybeasMaybeimportData.Monoid(Monoid(..))importData.Traversable(Traversable(traverse))importPreludehiding(filter,foldl,foldr,lookup,map,null)importqualifiedPrelude#if __GLASGOW_HASKELL__importText.Read(readPrec,lexP,parens,prec,Lexeme(Ident))#endifimportqualifiedData.ListTrie.Base.MapasMapimportqualifiedData.ListTrie.Patricia.BaseasBaseimportData.ListTrie.Base.Classes(fmap')importData.ListTrie.Base.Map(Map,OrdMap)#include "docs.h"-- Invariant: any (Tr Nothing _ _) has at least two children, all of which are-- Just or have a Just descendant.---- In order to avoid a lot of special casing it has to be the case that there's-- only one way to represent a given trie. The above property makes sure of-- that, so that, for instance, 'fromList [("foo",1)]' can only be 'Tr (Just 1)-- "foo" Map.empty', and not 'Tr Nothing "fo" (Map.fromList [('o',Tr (Just 1)-- "" Map.empty)])'. Base.tryCompress is a function which takes care of this.---- | The data structure itself: a map from keys of type @[k]@ to values of type-- @v@ implemented as a trie, using @map@ to map keys of type @k@ to sub-tries.---- Regarding the instances:---- - The @Trie@ class is internal, ignore it.---- - The 'Eq' constraint for the 'Ord' instance is misleading: it is needed-- only because 'Eq' is a superclass of 'Ord'.---- - The 'Foldable' and 'Traversable' instances allow folding over and-- traversing only the values, not the keys.---- - The 'Monoid' instance defines 'mappend' as 'union' and 'mempty' as-- 'empty'.dataTrieMapmapkv=Tr(Maybev)![k]!(CMapmapkv)typeCMapmapkv=mapk(TrieMapmapkv)instanceMapmapk=>Base.TrieTrieMapMaybemapkwheremkTrie=TrtParts(Trvpm)=(v,p,m)-- Don't use CMap in these instances since Haddock won't expand itinstance(Mapmapk,Eq(mapk(TrieMapmapka)),Eqa)=>Eq(TrieMapmapka)whereTrv1p1m1==Trv2p2m2=v1==v2&&Base.eqComparePrefixes(Map.eqCmpm1)p1p2&&m1==m2-- Eq constraint only needed because of superclassness... sighinstance(Eq(mapk(TrieMapmapka)),OrdMapmapk,Ordk,Orda)=>Ord(TrieMapmapka)wherecompare=compare`on`toAscListinstanceMapmapk=>Monoid(TrieMapmapka)wheremempty=emptymappend=unionmconcat=unionsinstanceMapmapk=>Functor(TrieMapmapk)wherefmap=mapinstanceMapmapk=>F.Foldable(TrieMapmapk)wherefoldl=foldl.flipfoldr=foldrinstance(Mapmapk,Traversable(mapk))=>Traversable(TrieMapmapk)wheretraversef(Trvpm)=flipTrp<$>traversefv<*>traverse(traversef)minstance(Mapmapk,Showk,Showa)=>Show(TrieMapmapka)whereshowsPrecps=showParen(p>10)$showString"fromList ".shows(toLists)instance(Mapmapk,Readk,Reada)=>Read(TrieMapmapka)where#if __GLASGOW_HASKELL__readPrec=parens$prec10$doIdent"fromList"<-lexPfmapfromListreadPrec#elsereadsPrecp=readParen(p>10)$\r->do("fromList",list)<-lexr(xs,rest)<-readsPrec(p+1)list[(fromListxs,rest)]#endif-- * Construction-- | @O(1)@. The empty map.empty::Mapmapk=>TrieMapmapkaempty=Base.empty-- | @O(1)@. The singleton map containing only the given key-value pair.singleton::Mapmapk=>[k]->a->TrieMapmapkasingleton=Base.singleton-- * Modification-- | @O(min(m,s))@. Inserts the key-value pair into the map. If the key is-- already a member of the map, the given value replaces the old one.---- > insert = insertWith constinsert::Mapmapk=>[k]->a->TrieMapmapka->TrieMapmapkainsert=Base.insert-- | @O(min(m,s))@. Like 'insert', but the new value is reduced to weak head-- normal form before being placed into the map.---- > insert' = insertWith' constinsert'::Mapmapk=>[k]->a->TrieMapmapka->TrieMapmapkainsert'=Base.insert'-- | @O(min(m,s))@. Inserts the key-value pair into the map. If the key is-- already a member of the map, the old value is replaced by @f givenValue-- oldValue@ where @f@ is the given function.insertWith::Mapmapk=>(a->a->a)->[k]->a->TrieMapmapka->TrieMapmapkainsertWith=Base.insertWith-- | @O(min(m,s))@. Like 'insertWith', but the new value is reduced to weak-- head normal form before being placed into the map, whether it is the given-- value or a result of the combining function.insertWith'::Mapmapk=>(a->a->a)->[k]->a->TrieMapmapka->TrieMapmapkainsertWith'=Base.insertWith'-- | @O(min(m,s))@. Removes the key from the map along with its associated-- value. If the key is not a member of the map, the map is unchanged.delete::Mapmapk=>[k]->TrieMapmapka->TrieMapmapkadelete=Base.delete-- | @O(min(m,s))@. Adjusts the value at the given key by calling the given-- function on it. If the key is not a member of the map, the map is unchanged.adjust::Mapmapk=>(a->a)->[k]->TrieMapmapka->TrieMapmapkaadjust=Base.adjust-- | @O(min(m,s))@. Like 'adjust', but the function is applied strictly.adjust'::Mapmapk=>(a->a)->[k]->TrieMapmapka->TrieMapmapkaadjust'=Base.adjust'-- | @O(min(m,s))@. Updates the value at the given key: if the given-- function returns 'Nothing', the value and its associated key are removed; if-- 'Just'@ a@is returned, the old value is replaced with @a@. If the key is-- not a member of the map, the map is unchanged.update::Mapmapk=>(a->Maybea)->[k]->TrieMapmapka->TrieMapmapkaupdatefk=snd.updateLookupfk-- | @O(min(m,s))@. Like 'update', but also returns 'Just' the original value,-- or 'Nothing' if the key is not a member of the map.updateLookup::Mapmapk=>(a->Maybea)->[k]->TrieMapmapka->(Maybea,TrieMapmapka)updateLookup=Base.updateLookup-- | @O(min(m,s))@. The most general modification function, allowing you to-- modify the value at the given key, whether or not it is a member of the map.-- In short: the given function is passed 'Just' the value at the key if it is-- present, or 'Nothing' otherwise; if the function returns 'Just' a value, the-- new value is inserted into the map, otherwise the old value is removed. More-- precisely, for @alter f k m@:---- If @k@ is a member of @m@, @f (@'Just'@ oldValue)@ is called. Now:---- - If @f@ returned 'Just'@ newValue@, @oldValue@ is replaced with @newValue@.---- - If @f@ returned 'Nothing', @k@ and @oldValue@ are removed from the map.---- If, instead, @k@ is not a member of @m@, @f @'Nothing' is called, and:---- - If @f@ returned 'Just'@ value@, @value@ is inserted into the map, at @k@.---- - If @f@ returned 'Nothing', the map is unchanged.---- The function is applied lazily only if the given key is a prefix of more-- than one key in the map.alter::Mapmapk=>(Maybea->Maybea)->[k]->TrieMapmapka->TrieMapmapkaalter=Base.alter-- | @O(min(m,s))@. Like 'alter', but the function is always applied strictly.alter'::Mapmapk=>(Maybea->Maybea)->[k]->TrieMapmapka->TrieMapmapkaalter'=Base.alter'-- * Querying-- | @O(1)@. 'True' iff the map is empty.null::Mapmapk=>TrieMapmapka->Boolnull=Base.null-- | @O(n m)@. The number of elements in the map. The value is built up lazily,-- allowing for delivery of partial results without traversing the whole map.size::(Mapmapk,Numn)=>TrieMapmapka->nsize=Base.size-- | @O(n m)@. The number of elements in the map. The value is built strictly:-- no value is returned until the map has been fully traversed.size'::(Mapmapk,Numn)=>TrieMapmapka->nsize'=Base.size'-- | @O(min(m,s))@. 'True' iff the given key is associated with a value in the-- map.member::Mapmapk=>[k]->TrieMapmapka->Boolmember=Base.member-- | @O(min(m,s))@. 'False' iff the given key is associated with a value in the-- map.notMember::Mapmapk=>[k]->TrieMapmapka->BoolnotMember=Base.notMember-- | @O(min(m,s))@. 'Just' the value in the map associated with the given key,-- or 'Nothing' if the key is not a member of the map.lookup::Mapmapk=>[k]->TrieMapmapka->Maybealookup=Base.lookup-- | @O(min(m,s))@. Like 'lookup', but returns the given value when the key is-- not a member of the map.lookupWithDefault::Mapmapk=>a->[k]->TrieMapmapka->alookupWithDefault=Base.lookupWithDefault-- | @O(min(n1 m1,n2 m2))@. 'True' iff the first map is a submap of the second,-- i.e. all keys that are members of the first map are also members of the-- second map, and their associated values are the same.---- > isSubmapOf = isSubmapOfBy (==)isSubmapOf::(Mapmapk,Eqa)=>TrieMapmapka->TrieMapmapka->BoolisSubmapOf=isSubmapOfBy(==)-- | @O(min(n1 m1,n2 m2))@. Like 'isSubmapOf', but one can specify the equality-- relation applied to the values.---- 'True' iff all keys that are members of the first map are also members of-- the second map, and the given function @f@ returns 'True' for all @f-- firstMapValue secondMapValue@ where @firstMapValue@ and @secondMapValue@ are-- associated with the same key.isSubmapOfBy::Mapmapk=>(a->b->Bool)->TrieMapmapka->TrieMapmapkb->BoolisSubmapOfBy=Base.isSubmapOfBy-- | @O(min(n1 m1,n2 m2))@. 'True' iff the first map is a proper submap of the-- second, i.e. all keys that are members of the first map are also members of-- the second map, and their associated values are the same, but the maps are-- not equal. That is, at least one key was a member of the second map but not-- the first.---- > isProperSubmapOf = isProperSubmapOfBy (==)isProperSubmapOf::(Mapmapk,Eqa)=>TrieMapmapka->TrieMapmapka->BoolisProperSubmapOf=isProperSubmapOfBy(==)-- | @O(min(n1 m1,n2 m2))@. Like 'isProperSubmapOf', but one can specify the-- equality relation applied to the values.---- 'True' iff all keys that are members of the first map are also members of-- the second map, and the given function @f@ returns 'True' for all @f-- firstMapValue secondMapValue@ where @firstMapValue@ and @secondMapValue@ are-- associated with the same key, and at least one key in the second map is not-- a member of the first.isProperSubmapOfBy::Mapmapk=>(a->b->Bool)->TrieMapmapka->TrieMapmapkb->BoolisProperSubmapOfBy=Base.isProperSubmapOfBy-- * CombinationdefaultUnion::a->a->adefaultUnion=const-- | @O(min(n1 m1,n2 m2))@. The union of the two maps: the map which contains-- all keys that are members of either map. This union is left-biased: if a key-- is a member of both maps, the value from the first map is chosen.---- The worst-case performance occurs when the two maps are identical.---- > union = unionWith constunion::Mapmapk=>TrieMapmapka->TrieMapmapka->TrieMapmapkaunion=unionWithdefaultUnion-- | @O(min(n1 m1,n2 m2))@. Like 'union', but the combining function ('const')-- is applied strictly.---- > union' = unionWith' constunion'::Mapmapk=>TrieMapmapka->TrieMapmapka->TrieMapmapkaunion'=unionWith'defaultUnion-- | @O(min(n1 m1,n2 m2))@. Like 'union', but the given function is used to-- determine the new value if a key is a member of both given maps. For a-- function @f@, the new value is @f firstMapValue secondMapValue@.unionWith::Mapmapk=>(a->a->a)->TrieMapmapka->TrieMapmapka->TrieMapmapkaunionWith=Base.unionWith-- | @O(min(n1 m1,n2 m2))@. Like 'unionWith', but the combining function is-- applied strictly.unionWith'::Mapmapk=>(a->a->a)->TrieMapmapka->TrieMapmapka->TrieMapmapkaunionWith'=Base.unionWith'-- | @O(min(n1 m1,n2 m2))@. Like 'unionWith', but in addition to the two-- values, the key is passed to the combining function.unionWithKey::Mapmapk=>([k]->a->a->a)->TrieMapmapka->TrieMapmapka->TrieMapmapkaunionWithKey=Base.unionWithKey-- | @O(min(n1 m1,n2 m2))@. Like 'unionWithKey', but the combining function is-- applied strictly.unionWithKey'::Mapmapk=>([k]->a->a->a)->TrieMapmapka->TrieMapmapka->TrieMapmapkaunionWithKey'=Base.unionWithKey'-- | @O(sum(n))@. The union of all the maps: the map which contains all keys-- that are members of any of the maps. If a key is a member of multiple maps,-- the value that occurs in the earliest of the maps (according to the order of-- the given list) is chosen.---- The worst-case performance occurs when all the maps are identical.---- > unions = unionsWith constunions::Mapmapk=>[TrieMapmapka]->TrieMapmapkaunions=unionsWithdefaultUnion-- | @O(sum(n))@. Like 'unions', but the combining function ('const') is-- applied strictly.---- > unions' = unionsWith' constunions'::Mapmapk=>[TrieMapmapka]->TrieMapmapkaunions'=unionsWith'defaultUnion-- | @O(sum(n))@. Like 'unions', but the given function determines the final-- value if a key is a member of more than one map. The function is applied as-- a left fold over the values in the given list's order. For example:---- > unionsWith (-) [fromList [("a",1)],fromList [("a",2)],fromList [("a",3)]]-- > == fromList [("a",(1-2)-3)]-- > == fromList [("a",-4)]unionsWith::Mapmapk=>(a->a->a)->[TrieMapmapka]->TrieMapmapkaunionsWith=Base.unionsWith-- | @O(sum(n))@. Like 'unionsWith', but the combining function is applied-- strictly.unionsWith'::Mapmapk=>(a->a->a)->[TrieMapmapka]->TrieMapmapkaunionsWith'=Base.unionsWith'-- | @O(sum(n))@. Like 'unionsWith', but in addition to the two values under-- consideration, the key is passed to the combining function.unionsWithKey::Mapmapk=>([k]->a->a->a)->[TrieMapmapka]->TrieMapmapkaunionsWithKey=Base.unionsWithKey-- | @O(sum(n))@. Like 'unionsWithKey', but the combining function is applied-- strictly.unionsWithKey'::Mapmapk=>([k]->a->a->a)->[TrieMapmapka]->TrieMapmapkaunionsWithKey'=Base.unionsWithKey'-- | @O(min(n1 m1,n2 m2))@. The difference of the two maps: the map which-- contains all keys that are members of the first map and not of the second.---- The worst-case performance occurs when the two maps are identical.---- > difference = differenceWith (\_ _ -> Nothing)difference::Mapmapk=>TrieMapmapka->TrieMapmapkb->TrieMapmapkadifference=differenceWith(\__->Nothing)-- | @O(min(n1 m1,n2 m2))@. Like 'difference', but the given function-- determines what to do when a key is a member of both maps. If the function-- returns 'Nothing', the key is removed; if it returns 'Just' a new value,-- that value replaces the old one in the first map.differenceWith::Mapmapk=>(a->b->Maybea)->TrieMapmapka->TrieMapmapkb->TrieMapmapkadifferenceWith=Base.differenceWith-- | @O(min(n1 m1,n2 m2))@. Like 'differenceWith', but in addition to the two-- values, the key they are associated with is passed to the combining-- function.differenceWithKey::Mapmapk=>([k]->a->b->Maybea)->TrieMapmapka->TrieMapmapkb->TrieMapmapkadifferenceWithKey=Base.differenceWithKey-- | @O(min(n1 m1,n2 m2))@. The intersection of the two maps: the map which-- contains all keys that are members of both maps.---- The worst-case performance occurs when the two maps are identical.---- > intersection = intersectionWith constintersection::Mapmapk=>TrieMapmapka->TrieMapmapkb->TrieMapmapkaintersection=intersectionWithconst-- | @O(min(n1 m1,n2 m2))@. Like 'intersection', but the combining function is-- applied strictly.---- > intersection' = intersectionWith' constintersection'::Mapmapk=>TrieMapmapka->TrieMapmapkb->TrieMapmapkaintersection'=intersectionWith'const-- | @O(min(n1 m1,n2 m2))@. Like 'intersection', but the given function-- determines the new values.intersectionWith::Mapmapk=>(a->b->c)->TrieMapmapka->TrieMapmapkb->TrieMapmapkcintersectionWith=Base.intersectionWith-- | @O(min(n1 m1,n2 m2))@. Like 'intersectionWith', but the combining function-- is applied strictly.intersectionWith'::Mapmapk=>(a->b->c)->TrieMapmapka->TrieMapmapkb->TrieMapmapkcintersectionWith'=Base.intersectionWith'-- | @O(min(n1 m1,n2 m2))@. Like 'intersectionWith', but in addition to the two-- values, the key they are associated with is passed to the combining-- function.intersectionWithKey::Mapmapk=>([k]->a->b->c)->TrieMapmapka->TrieMapmapkb->TrieMapmapkcintersectionWithKey=Base.intersectionWithKey-- | @O(min(n1 m1,n2 m2))@. Like 'intersectionWithKey', but the combining-- function is applied strictly.intersectionWithKey'::Mapmapk=>([k]->a->b->c)->TrieMapmapka->TrieMapmapkb->TrieMapmapkcintersectionWithKey'=Base.intersectionWithKey'-- * Filtering-- | @O(n m)@. Apply the given function to the elements in the map, discarding-- those for which the function returns 'False'.filter::Mapmapk=>(a->Bool)->TrieMapmapka->TrieMapmapkafilter=filterWithKey.const-- | @O(n m)@. Like 'filter', but the key associated with the element is also-- passed to the given predicate.filterWithKey::Mapmapk=>([k]->a->Bool)->TrieMapmapka->TrieMapmapkafilterWithKey=Base.filterWithKey-- | @O(n m)@. A pair of maps: the first element contains those values for-- which the given predicate returns 'True', and the second contains those for-- which it was 'False'.partition::Mapmapk=>(a->Bool)->TrieMapmapka->(TrieMapmapka,TrieMapmapka)partition=partitionWithKey.const-- | @O(n m)@. Like 'partition', but the key associated with the element is-- also passed to the given predicate.partitionWithKey::Mapmapk=>([k]->a->Bool)->TrieMapmapka->(TrieMapmapka,TrieMapmapka)partitionWithKey=Base.partitionWithKey-- | @O(n m)@. Apply the given function to the elements in the map, preserving-- only the 'Just' results.mapMaybe::Mapmapk=>(a->Maybeb)->TrieMapmapka->TrieMapmapkbmapMaybe=mapMaybeWithKey.const-- | @O(n m)@. Like 'mapMaybe', but the key associated with the element is also-- passed to the given function.mapMaybeWithKey::Mapmapk=>([k]->a->Maybeb)->TrieMapmapka->TrieMapmapkbmapMaybeWithKeyf=fromList.Maybe.mapMaybe(\(k,v)->fmap((,)k)(fkv)).toList-- | @O(n m)@. Apply the given function to the elements in the map, separating-- the 'Left' results from the 'Right'. The first element of the pair contains-- the former results, and the second the latter.mapEither::Mapmapk=>(a->Eitherbc)->TrieMapmapka->(TrieMapmapkb,TrieMapmapkc)mapEither=mapEitherWithKey.const-- | @O(n m)@. Like 'mapEither', but the key associated with the element is-- also passed to the given function.mapEitherWithKey::Mapmapk=>([k]->a->Eitherbc)->TrieMapmapka->(TrieMapmapkb,TrieMapmapkc)mapEitherWithKeyf=(fromList***fromList).partitionEithers.Prelude.map(\(k,v)->either(Left.(,)k)(Right.(,)k)(fkv)).toList-- * Mapping-- | @O(n m)@. Apply the given function to all the elements in the map.map::Mapmapk=>(a->b)->TrieMapmapka->TrieMapmapkbmap=genericMapfmap-- | @O(n m)@. Like 'map', but apply the function strictly.map'::Mapmapk=>(a->b)->TrieMapmapka->TrieMapmapkbmap'=genericMapfmap'genericMap::Mapmapk=>((a->b)->Maybea->Maybeb)->(a->b)->TrieMapmapka->TrieMapmapkbgenericMapmyFmapf(Trvpm)=Tr(myFmapfv)p(Map.map(genericMapmyFmapf)m)-- | @O(n m)@. Like 'map', but also pass the key associated with the element to-- the given function.mapWithKey::Mapmapk=>([k]->a->b)->TrieMapmapka->TrieMapmapkbmapWithKey=genericMapWithKeyfmap-- | @O(n m)@. Like 'mapWithKey', but apply the function strictly.mapWithKey'::Mapmapk=>([k]->a->b)->TrieMapmapka->TrieMapmapkbmapWithKey'=genericMapWithKeyfmap'genericMapWithKey::Mapmapk=>((a->b)->Maybea->Maybeb)->([k]->a->b)->TrieMapmapka->TrieMapmapkbgenericMapWithKey=goDL.emptywheregokmyFmapf(Trvpm)=letk'=k`DL.append`DL.fromListpinTr(myFmap(f$DL.toListk')v)p(Map.mapWithKey(\x->go(k'`DL.snoc`x)myFmapf)m)-- | @O(n m)@. Apply the given function to all the keys in a map.---- > mapKeys = mapKeysWith constmapKeys::(Mapmapk1,Mapmapk2)=>([k1]->[k2])->TrieMapmapk1a->TrieMapmapk2amapKeys=mapKeysWithconst-- | @O(n m)@. Like 'mapKeys', but use the first given function to combine-- elements if the second function gives two keys the same value.mapKeysWith::(Mapmapk1,Mapmapk2)=>(a->a->a)->([k1]->[k2])->TrieMapmapk1a->TrieMapmapk2amapKeysWith=Base.mapKeysWith.fromListWith-- | @O(n m)@. Apply the given function to the contents of all the keys in the-- map.---- > mapInKeys = mapInKeysWith constmapInKeys::(Mapmapk1,Mapmapk2)=>(k1->k2)->TrieMapmapk1a->TrieMapmapk2amapInKeys=mapInKeysWithdefaultUnion-- | @O(n m)@. Like 'mapInKeys', but combine identical keys strictly.---- > mapInKeys' = mapInKeysWith' constmapInKeys'::(Mapmapk1,Mapmapk2)=>(k1->k2)->TrieMapmapk1a->TrieMapmapk2amapInKeys'=mapInKeysWith'defaultUnion-- | @O(n m)@. Like 'mapInKeys', but use the first given function to combine-- elements if the second function gives two keys the same value.mapInKeysWith::(Mapmapk1,Mapmapk2)=>(a->a->a)->(k1->k2)->TrieMapmapk1a->TrieMapmapk2amapInKeysWith=Base.mapInKeysWith-- | @O(n m)@. Like 'mapInKeysWith', but apply the combining function strictly.mapInKeysWith'::(Mapmapk1,Mapmapk2)=>(a->a->a)->(k1->k2)->TrieMapmapk1a->TrieMapmapk2amapInKeysWith'=Base.mapInKeysWith'-- | @O(n m)@. Like "Data.List".@mapAccumL@ on the 'toList' representation.---- Essentially a combination of 'map' and 'foldl': the given-- function is applied to each element of the map, resulting in a new value for-- the accumulator and a replacement element for the map.mapAccum::Mapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccum=genericMapAccumMap.mapAccum(flipconst)-- | @O(n m)@. Like 'mapAccum', but the function is applied strictly.mapAccum'::Mapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccum'=genericMapAccumMap.mapAccumseq-- | @O(n m)@. Like 'mapAccum', but the function receives the key in addition-- to the value associated with it.mapAccumWithKey::Mapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumWithKey=genericMapAccumWithKeyMap.mapAccumWithKey(flipconst)-- | @O(n m)@. Like 'mapAccumWithKey', but the function is applied strictly.mapAccumWithKey'::Mapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumWithKey'=genericMapAccumWithKeyMap.mapAccumWithKeyseq-- | @O(n m)@. Like 'mapAccum', but in ascending order, as though operating on-- the 'toAscList' representation.mapAccumAsc::OrdMapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumAsc=genericMapAccumMap.mapAccumAsc(flipconst)-- | @O(n m)@. Like 'mapAccumAsc', but the function is applied strictly.mapAccumAsc'::OrdMapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumAsc'=genericMapAccumMap.mapAccumAscseq-- | @O(n m)@. Like 'mapAccumAsc', but the function receives the key in-- addition to the value associated with it.mapAccumAscWithKey::OrdMapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumAscWithKey=genericMapAccumWithKeyMap.mapAccumAscWithKey(flipconst)-- | @O(n m)@. Like 'mapAccumAscWithKey', but the function is applied strictly.mapAccumAscWithKey'::OrdMapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumAscWithKey'=genericMapAccumWithKeyMap.mapAccumAscWithKeyseq-- | @O(n m)@. Like 'mapAccum', but in descending order, as though operating on-- the 'toDescList' representation.mapAccumDesc::OrdMapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumDesc=genericMapAccumMap.mapAccumDesc(flipconst)-- | @O(n m)@. Like 'mapAccumDesc', but the function is applied strictly.mapAccumDesc'::OrdMapmapk=>(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumDesc'=genericMapAccumMap.mapAccumDescseq-- | @O(n m)@. Like 'mapAccumDesc', but the function receives the key in-- addition to the value associated with it.mapAccumDescWithKey::OrdMapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumDescWithKey=genericMapAccumWithKeyMap.mapAccumDescWithKey(flipconst)-- | @O(n m)@. Like 'mapAccumDescWithKey', but the function is applied-- strictly.mapAccumDescWithKey'::OrdMapmapk=>(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)mapAccumDescWithKey'=genericMapAccumWithKeyMap.mapAccumDescWithKeyseqgenericMapAccum::Mapmapk=>((acc->TrieMapmapka->(acc,TrieMapmapkb))->acc->CMapmapka->(acc,CMapmapkb))->(b->(acc,Maybeb)->(acc,Maybeb))->(acc->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)genericMapAccumsubMapAccumseeqfacc(Trmvpm)=let(acc',mv')=casemvofNothing->(acc,Nothing)Justv->let(acc'',v')=faccvinv'`seeq`(acc'',Justv')insecond(Trmv'p)$subMapAccum(genericMapAccumsubMapAccumseeqf)acc'mgenericMapAccumWithKey::Mapmapk=>((acc->k->TrieMapmapka->(acc,TrieMapmapkb))->acc->CMapmapka->(acc,CMapmapkb))->(b->(acc,Maybeb)->(acc,Maybeb))->(acc->[k]->a->(acc,b))->acc->TrieMapmapka->(acc,TrieMapmapkb)genericMapAccumWithKey=goDL.emptywheregoksubMapAccumseeqfacc(Trmvpm)=letk'=k`DL.append`DL.fromListp(acc',mv')=casemvofNothing->(acc,Nothing)Justv->let(acc'',v')=facc(DL.toListk')vinv'`seeq`(acc'',Justv')insecond(Trmv'p)$subMapAccum(\ax->go(k'`DL.snoc`x)subMapAccumseeqfa)acc'm-- * Folding-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toList' representation,-- folding only over the elements.foldr::Mapmapk=>(a->b->b)->b->TrieMapmapka->bfoldr=foldrWithKey.const-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toList' representation,-- folding over both the keys and the elements.foldrWithKey::Mapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldrWithKey=Base.foldrWithKey-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toAscList' representation.foldrAsc::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldrAsc=foldrAscWithKey.const-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toAscList' representation,-- folding over both the keys and the elements.foldrAscWithKey::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldrAscWithKey=Base.foldrAscWithKey-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toDescList' representation.foldrDesc::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldrDesc=foldrDescWithKey.const-- | @O(n m)@. Equivalent to a list @foldr@ on the 'toDescList' representation,-- folding over both the keys and the elements.foldrDescWithKey::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldrDescWithKey=Base.foldrDescWithKey-- | @O(n m)@. Equivalent to a list @foldl@ on the toList representation.foldl::Mapmapk=>(a->b->b)->b->TrieMapmapka->bfoldl=foldlWithKey.const-- | @O(n m)@. Equivalent to a list @foldl@ on the toList representation,-- folding over both the keys and the elements.foldlWithKey::Mapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlWithKey=Base.foldlWithKey-- | @O(n m)@. Equivalent to a list @foldl@ on the toAscList representation.foldlAsc::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldlAsc=foldlAscWithKey.const-- | @O(n m)@. Equivalent to a list @foldl@ on the toAscList representation,-- folding over both the keys and the elements.foldlAscWithKey::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlAscWithKey=Base.foldlAscWithKey-- | @O(n m)@. Equivalent to a list @foldl@ on the toDescList representation.foldlDesc::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldlDesc=foldlDescWithKey.const-- | @O(n m)@. Equivalent to a list @foldl@ on the toDescList representation,-- folding over both the keys and the elements.foldlDescWithKey::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlDescWithKey=Base.foldlDescWithKey-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toList' representation.foldl'::Mapmapk=>(a->b->b)->b->TrieMapmapka->bfoldl'=foldlWithKey'.const-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toList' representation,-- folding over both the keys and the elements.foldlWithKey'::Mapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlWithKey'=Base.foldlWithKey'-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toAscList' representation.foldlAsc'::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldlAsc'=foldlAscWithKey'.const-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toAscList' representation,-- folding over both the keys and the elements.foldlAscWithKey'::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlAscWithKey'=Base.foldlAscWithKey'-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toDescList'-- representation.foldlDesc'::OrdMapmapk=>(a->b->b)->b->TrieMapmapka->bfoldlDesc'=foldlDescWithKey'.const-- | @O(n m)@. Equivalent to a list @foldl'@ on the 'toDescList'-- representation, folding over both the keys and the elements.foldlDescWithKey'::OrdMapmapk=>([k]->a->b->b)->b->TrieMapmapka->bfoldlDescWithKey'=Base.foldlDescWithKey'-- * Conversion between lists-- | @O(n m)@. Converts the map to a list of the key-value pairs contained-- within, in undefined order.toList::Mapmapk=>TrieMapmapka->[([k],a)]toList=Base.toList-- | @O(n m)@. Converts the map to a list of the key-value pairs contained-- within, in ascending order.toAscList::OrdMapmapk=>TrieMapmapka->[([k],a)]toAscList=Base.toAscList-- | @O(n m)@. Converts the map to a list of the key-value pairs contained-- within, in descending order.toDescList::OrdMapmapk=>TrieMapmapka->[([k],a)]toDescList=Base.toDescList-- | @O(n m)@. Creates a map from a list of key-value pairs. If a key occurs-- more than once, the value from the last pair (according to the list's order)-- is the one which ends up in the map.---- > fromList = fromListWith constfromList::Mapmapk=>[([k],a)]->TrieMapmapkafromList=Base.fromList-- | @O(n m)@. Like 'fromList', but the given function is used to determine the-- final value if a key occurs more than once. The function is applied as-- though it were flipped and then applied as a left fold over the values in-- the given list's order. Or, equivalently (except as far as performance is-- concerned), as though the function were applied as a right fold over the-- values in the reverse of the given list's order. For example:---- > fromListWith (-) [("a",1),("a",2),("a",3),("a",4)]-- > == fromList [("a",4-(3-(2-1)))]-- > == fromList [("a",2)]fromListWith::Mapmapk=>(a->a->a)->[([k],a)]->TrieMapmapkafromListWith=Base.fromListWith-- | @O(n m)@. Like 'fromListWith', but the combining function is applied-- strictly.fromListWith'::Mapmapk=>(a->a->a)->[([k],a)]->TrieMapmapkafromListWith'=Base.fromListWith'-- | @O(n m)@. Like 'fromListWith', but the key, in addition to the values to-- be combined, is passed to the combining function.fromListWithKey::Mapmapk=>([k]->a->a->a)->[([k],a)]->TrieMapmapkafromListWithKey=Base.fromListWithKey-- | @O(n m)@. Like 'fromListWithKey', but the combining function is applied-- strictly.fromListWithKey'::Mapmapk=>([k]->a->a->a)->[([k],a)]->TrieMapmapkafromListWithKey'=Base.fromListWithKey'-- * Ordering ops-- | @O(m)@. Removes and returns the minimal key in the map, along with the-- value associated with it. If the map is empty, 'Nothing' and the original-- map are returned.minView::OrdMapmapk=>TrieMapmapka->(Maybe([k],a),TrieMapmapka)minView=Base.minView-- | @O(m)@. Removes and returns the maximal key in the map, along with the-- value associated with it. If the map is empty, 'Nothing' and the original-- map are returned.maxView::OrdMapmapk=>TrieMapmapka->(Maybe([k],a),TrieMapmapka)maxView=Base.maxView-- | @O(m)@. Like 'fst' composed with 'minView'. 'Just' the minimal key in the-- map and its associated value, or 'Nothing' if the map is empty.findMin::OrdMapmapk=>TrieMapmapka->Maybe([k],a)findMin=Base.findMin-- | @O(m)@. Like 'fst' composed with 'maxView'. 'Just' the minimal key in the-- map and its associated value, or 'Nothing' if the map is empty.findMax::OrdMapmapk=>TrieMapmapka->Maybe([k],a)findMax=Base.findMax-- | @O(m)@. Like 'snd' composed with 'minView'. The map without its minimal-- key, or the unchanged original map if it was empty.deleteMin::OrdMapmapk=>TrieMapmapka->TrieMapmapkadeleteMin=Base.deleteMin-- | @O(m)@. Like 'snd' composed with 'maxView'. The map without its maximal-- key, or the unchanged original map if it was empty.deleteMax::OrdMapmapk=>TrieMapmapka->TrieMapmapkadeleteMax=Base.deleteMax-- | @O(min(m,s))@. Splits the map in two about the given key. The first-- element of the resulting pair is a map containing the keys lesser than the-- given key; the second contains those keys that are greater.split::OrdMapmapk=>[k]->TrieMapmapka->(TrieMapmapka,TrieMapmapka)split=Base.split-- | @O(min(m,s))@. Like 'split', but also returns the value associated with-- the given key, if any.splitLookup::OrdMapmapk=>[k]->TrieMapmapka->(TrieMapmapka,Maybea,TrieMapmapka)splitLookup=Base.splitLookup-- | @O(m)@. 'Just' the key of the map which precedes the given key in order,-- along with its associated value, or 'Nothing' if the map is empty.findPredecessor::OrdMapmapk=>[k]->TrieMapmapka->Maybe([k],a)findPredecessor=Base.findPredecessor-- | @O(m)@. 'Just' the key of the map which succeeds the given key in order,-- along with its associated value, or 'Nothing' if the map is empty.findSuccessor::OrdMapmapk=>[k]->TrieMapmapka->Maybe([k],a)findSuccessor=Base.findSuccessor-- * Trie-only operations-- | @O(s)@. Prepends the given key to all the keys of the map. For example:---- > addPrefix "xa" (fromList [("a",1),("b",2)])-- > == fromList [("xaa",1),("xab",2)]addPrefix::Mapmapk=>[k]->TrieMapmapka->TrieMapmapkaaddPrefix=Base.addPrefix-- | @O(m)@. The map which contains all keys of which the given key is a-- prefix, with the prefix removed from each key. If the given key is not a-- prefix of any key in the map, the map is returned unchanged. For example:---- > deletePrefix "a" (fromList [("a",1),("ab",2),("ac",3)])-- > == fromList [("",1),("b",2),("c",3)]---- This function can be used, for instance, to reduce potentially expensive I/O-- operations: if you need to find the value in a map associated with a string,-- but you only have a prefix of it and retrieving the rest is an expensive-- operation, calling 'deletePrefix' with what you have might allow you to-- avoid the operation: if the resulting map is empty, the entire string cannot-- be a member of the map.deletePrefix::Mapmapk=>[k]->TrieMapmapka->TrieMapmapkadeletePrefix=Base.deletePrefix-- | @O(1)@. A triple containing the longest common prefix of all keys in the-- map, the value associated with that prefix, if any, and the map with that-- prefix removed from all the keys as well as the map itself. Examples:---- > splitPrefix (fromList [("a",1),("b",2)])-- > == ("", Nothing, fromList [("a",1),("b",2)])-- > splitPrefix (fromList [("a",1),("ab",2),("ac",3)])-- > == ("a", Just 1, fromList [("b",2),("c",3)])splitPrefix::Mapmapk=>TrieMapmapka->([k],Maybea,TrieMapmapka)splitPrefix=Base.splitPrefix-- | @O(1)@. The children of the longest common prefix in the trie as maps,-- associated with their distinguishing key value. If the map contains less-- than two keys, this function will return the empty list. Examples;---- > children (fromList [("a",1),("abc",2),("abcd",3)])-- > == [('b',fromList [("c",2),("cd",3)])]-- > children (fromList [("b",1),("c",2)])-- > == [('b',fromList [("",1)]),('c',fromList [("",2)])]children::Mapmapk=>TrieMapmapka->[(k,TrieMapmapka)]children=Base.children-- * Visualization-- | @O(n m)@. Displays the map's internal structure in an undefined way. That-- is to say, no program should depend on the function's results.showTrie::(Showk,Showa,Mapmapk)=>TrieMapmapka->ShowSshowTrie=Base.showTrieWith$\mv->casemvofNothing->showChar' 'Justv->showsPrec11v-- | @O(n m)@. Like 'showTrie', but uses the given function to display the-- elements of the map. Still undefined.showTrieWith::(Showk,Mapmapk)=>(Maybea->ShowS)->TrieMapmapka->ShowSshowTrieWith=Base.showTrieWith