uPV      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUUses GHC extensions experimentalNone3'A map of keys to values. The keys are V types but are stored as Ws  so any keys with the same W/ value are treated as the same. The aim is to  provide typesafe indexing. &No subtrees should be empty. Returns X if one is. YRemove empty subtrees. Join a key so that an  of  s becomes an  .  # newtype ID = ID Int deriving Enum 4 emm :: EnumMapMap (K Int) (EnumMapMap (K ID) Bool) & res :: EnumMapMap (Int :& K ID) Bool  res = joinKey emm  is the opposite of .. 6 emm = empty :: EnumMapMap (Int :& Int :& K ID) Bool) " emm == joinKey $ splitKey d2 emm Join a key so that an  of  s becomes an  <. The unsafe version does not check for empty subtrees, so  it is faster. # newtype ID = ID Int deriving Enum 4 emm :: EnumMapMap (K Int) (EnumMapMap (K ID) Bool) & res :: EnumMapMap (Int :& K ID) Bool  res = unsafeJoinKey emm  The empty . Is the  empty? FSubmaps can never be empty, so the following should always hold true: . emm :: EnumMapMap (Int :& Int :& K ID) Bool)  null $ splitKey x emm == False Number of elements in the . The expression ( f k emm) alters the value at k, or absence thereof.  8 can be used to insert, delete, or update a value in an . &Map a function over all values in the . Map a function over all key/value pairs in the . Fold the values in the # using the given right-associative  binary operator  Fold the keys and values in the # using the given right-associative  binary operator.  Convert the  to a list of key/ value pairs.  Create a  from a list of key/ value pairs. ,List of elements in ascending order of keys  List of keys The  of the keys.  keys can be converted into   keys using !, and back again using ".  Build an  from an  EnumMapSet and a function which for each  key computes it's value !The minimal key and value of the . ( findMin empty -- ERROR, no minimal key 7 findMin $ fromList [(K 1, "a", K 3, "b")] == (K 1, a) BRetrieves the minimal (key,value) pair of the EnumMapMap, and the ) EnumMapMap stripped of that element, or Z if passed an empty map. The (left-biased) union of two s.  It prefers the first & when duplicate keys are encountered. The union of a list of maps. 6The union of a list of maps with a combining function %The union with a combining function. %The union with a combining function. Difference between two s (based on keys). &Difference with a combining function. &Difference with a combining function. &The (left-biased) intersection of two  (based on keys). ,The intersection with a combining function. ,The intersection with a combining function. !Convert a key terminated with K into one terminated with S.  k = 1 :& 2 :& 'K' 3  toS k == 1 :& 2 :& 'S' 3 "Convert a key terminated with S into one terminated with K.  s = 1 :& 2 :& S 3  toK s == 1 :& 2 :& K 3 #The intersection of an  and an  EnumMapSet. If a key is D present in the EnumMapSet then it will be present in the resulting  . Works with  EnumMapSets that are submaps of the  . $The difference between an  and an  EnumMapSet . If a key  is present in the  EnumMapSet' it will not be present in the result. &!k1 should be a prefix of k2. If k1 ~ k2 then the & will be  v. ? Result (K ID1) (ID1 :& K ID2) v ~ EnumMapMap (K ID2) v , Result (ID1 :& K ID2) (ID1 :& K ID2) v ~ v 1 Result (ID1 :& K ID2) (K ID1) v -- ERROR 1 Result (ID2 :& K ID1) (ID1 :& K ID2) -- ERROR 'Is the key present in the ? (An  with one element 8 singleton (5 :& K 3) "a" == fromList [(5 :& K 3, "a")] E singleton (K 5) $ singleton (K 2) "a" == fromList [(5 :& K 3, "a")] )$Lookup up the value at a key in the .  " emm = fromList [(3 :& K 1, "a")] # lookup (3 :& K 1) emm == Just "a" " lookup (2 :& K 1) emm == Nothing .If the given key has less dimensions then the  then a submap  is returned. > emm2 = fromList [(3 :& 2 :& K 1, "a"), (3 :& 2 :& K 4, "a")] D lookup (3 :& K 2) emm2 == Just $ fromList [(K 1, "a"), (K 4, "a")] *Insert a new key/value pair into the . Can also insert submaps. +<Insert with a combining function. Can also insert submaps. ,<Insert with a combining function. Can also insert submaps. -Remove a key and it's value from the . If the key is not  present the original  is returned. .Split a key so that an  becomes an  of  s.  # newtype ID = ID Int deriving Enum . emm = empty :: EnumMapMap (Int :& K ID) Bool  res :: EnumMapMap (K ID) Bool & res = lookup (K 5) $ splitKey d1 emm FIf the level is too high then the compilation will fail with an error B emm = empty :: EnumMapMap (Int :& Int :& K Int) Bool -- 3 levels 8 res1 = splitKey d4 emm -- ERROR! Instance not found... 8 res2 = splitKey d3 emm -- ERROR! Instance not found...  res3 = splitKey d2 emm -- Good /!Multiple keys are joined by the (/) constructor. ! multiKey :: Int :& Int :& K Int  multiKey = 5 :& 6 :& K 5 1Split after 1 key. ( emm :: EnumMapMap (T1 :& T2 :& K T3) v B splitKey d1 emm :: EnumMapMap (T1 :& K T2) (EnumMapMap (K T3) v) 2Split after 2 keys. ( emm :: EnumMapMap (T1 :& T2 :& K T3) v B splitKey d1 emm :: EnumMapMap (K T1) (EnumMapMap (T2 :& K T3) v) [[+ is used to walk down the tree to find the  to actually  change. If the new  is null then it's removed from the containing  \. ]See IntMap% documentation for an explanation of ]. ^This instance differs from the _ instance in IntMap. Where the keys , are the same the values are combined using `. zaY  bcde!"f#$%&'()*+,-ghij.klmn/0opqr\stu123456789:v[wx]yz{|}~^daY  bcde!"f#$%&'()*+,-ghij.klmn/0opqr\stu123456789:wx]{|}~@$aY  bcde!"f#$%&'()*+,-ghij.klmn/0opqr\uts123456789:v[wx]yz{|}~^Uses GHC extensions experimentalNone;Keys are terminated with the ; type.  singleKey :: S Int  singleKey = S 5 ALookup a subtree in an =. / ems = fromList [1 :& 2 :& K 3, 1 :& 2 :& K 4] . lookup (1 :& K 2) ems == fromList [K 3, K 4] C lookup (1 :& 2 :& K 3) -- ERROR: Use 'member' to check for a key. HH f s! is the set obtained by applying f to each element of s. It'>s worth noting that the size of the result may be smaller if,  for some (x,y), x /= y && f x == f y 3;<=>?@ABCDEFGHIJKLMNOPQ$/0;<=>?@ABCDEFGHIJKLMNOPQ/;<=>?@ABCDEFGHIJKLMNOPQUses GHC extensions experimentalNone/0;<=>?@ABCDEFGHIJKLMNOPQ=;</0>?@ABCDELMNHFGPOQIJKUses GHC extensions experimentalNoneRKeys are terminated with the R type  singleKey :: K Int  singleKey = K 5 RS=  !"#$%&'()*+,-./0123456789:RS=/0RS  %&'()*+,-123456789:$#"!.RSUses GHC extensions experimentalNoneTKeys are terminated with the T type  singleKey :: K Int  singleKey = K 5 TU=  !"#$%&'()*+,-./0123456789:TU=/0TU  %&'()*+,-123456789:$#"!.TU      !"#$%&'()*+,-./01234567789:;<=>?@ABB/1 025CD#&EEEEFGHIJKIJLMFNOPQRSFTUFTVWXYZ[\]^_`aabbcdefghijklmnopqrstuvwxyz{|}~ghisuwenummapmap-0.5.0Data.EnumMapMap.StrictData.EnumMapSetData.EnumMapMap.LazyData.EnumMapMap.BaseData EnumMapSetData.EnumMapSet.BaseIsKey EnumMapMap emptySubTreesjoinKey unsafeJoinKeyemptynullsizealtermap mapWithKeyfoldr foldrWithKeytoListfromListelemskeyskeysSetfromSetfindMinminViewWithKey deleteFindMinunionunions unionsWith unionWith unionWithKey differencedifferenceWithdifferenceWithKey intersectionintersectionWithintersectionWithKeytoStoK intersectSet differenceSetSubKeyResultmember singletonlookupinsert insertWith insertWithKeydeletesplitKey:&d1d2d3d4d5d6d7d8d9d10SallminViewKbaseGHC.EnumEnumghc-prim GHC.TypesIntTrue removeEmpties Data.MaybeNothingalter_EMM mergeWithKey'$fMonoidEnumMapMap Data.MonoidMonoidmappendemptySubTrees_equalnequalHasSKeySkeySubKeySPlusIsSplitHeadTailNZMaskPrefixKeyNatNilTipBin insertWith_ mapWithKey_ foldrWithKey_equalEnequalE natFromInt intFromNatshiftRLshiftLLjoinjoinDbinbinDtipzeronomatchmatchmaskmaskWshorter branchMaskhighestBitMask foldlStrict$fDefaultEnumMapMap$fFoldableEnumMapMap $fNFData:&$fNFDataEnumMapMap$fShowEnumMapMap$fSemigroupEnumMapMap$fFunctorEnumMapMap$fEqEMM$fEqEnumMapMap $fIsKey:& $fSubKeyS:&:& $fSubKey:&:&v $fHasSKey:& $fIsSplit:&NKCCEMSBitMap insertSubinsertBMdeleteBM suffixBitMask prefixBitMaskprefixOfsuffixOfbitmapOfSuffixbitmapOfbitcountindexOfTheOnlyBit lowestBitMaskrevNat foldrBits lowestBitSet $fSubKeySS() $fSubKeyS:&() $fHasSKeyS$fIsKeySKSCmember_lookup_insert_insertWKdelete_fromSet_ intersectSet_differenceSet_ $fSubKeySKS $fSubKeyS:&S $fSubKeyKKv $fSubKeyK:&v $fIsSplit:&Z $fHasSKeyK $fNFDataK$fIsKeyK