i`aG      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFUses GHC extensions experimentalNone+G'A map of keys to values. The keys are H types but are stored as Is  so any keys with the same I/ value are treated as the same. The aim is to  provide typesafe indexing. &No subtrees should be empty. Returns J if one is. KRemove empty subtrees. Join a key so that an G of G s becomes an  G.  # 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 G of G s becomes an  G<. 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 G. Is the G 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 G. Is the key present in the G? 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 G. &Map a function over all values in the G. Map a function over all key/value pairs in the G. Fold the values in the G# using the given right-associative  binary operator  Fold the keys and values in the G# using the given right-associative  binary operator.  Convert the G to a list of key/ value pairs.  Create a G from a list of key/ value pairs. ,List of elements in ascending order of keys  List of keys The  of the keys. G keys can be converted into   keys using , and back again using . The (left-biased) union of two Gs.  It prefers the first G& when duplicate keys are encountered. The union of a list of maps. %The union with a combining function. %The union with a combining function. Difference between two Gs (based on keys). &Difference with a combining function. &Difference with a combining function. &The (left-biased) intersection of two G (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 An G 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 G.  " 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 G 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 G. 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 G. If the key is not  present the original G is returned. #Split a key so that an G becomes an G of  Gs.  # 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 &Split after 1 key. ( emm :: EnumMapMap (T1 :& T2 :& K T3) v B splitKey d1 emm :: EnumMapMap (T1 :& K T2) (EnumMapMap (K T3) v) 'Split after 2 keys. ( emm :: EnumMapMap (T1 :& T2 :& K T3) v B splitKey d1 emm :: EnumMapMap (K T1) (EnumMapMap (T2 :& K T3) v) LL+ is used to walk down the tree to find the G to actually  change. If the new G is null then it's removed from the containing  M. NSee IntMap% documentation for an explanation of N. mOGPK QRSTUV !"WXYZ#[\]^$%_`abMcde&'()*+,-./fLghNijklmnopqrstuvwxyz{|}~[OGPK QRSTUV !"WXYZ#[\]^$%_`abMcde&'()*+,-./ghNlmnoqstuvwyz|:O GPK QRSTUV !"WXYZ#[\]^$%_`abMedc&'()*+,-./fLghNijklmnopqrstuvwxyz{|}~Uses GHC extensions experimentalNone0Keys are terminated with the 0 type.  singleKey :: S Int  singleKey = S 5 6Lookup a subtree in an 2. / 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. << 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 -0123456789:;<=>?@AB G$%0123456789:;<=>?@AB)0123456789:;<=>?@ABUses GHC extensions experimentalNone$%0123456789:;<=>?@AB201$%3456789:=>?<;A@BUses GHC extensions experimentalNoneCKeys are terminated with the C type  singleKey :: K Int  singleKey = K 5 CD3G  !"#$%&'()*+,-./CD2$%CD&'()*+,-./ !" # CDUses GHC extensions experimentalNoneEKeys are terminated with the E type  singleKey :: K Int  singleKey = K 5 EF3G  !"#$%&'()*+,-./EF2$%EF&'()*+,-./ !" # EF      !"#$%&'()*+,,-./012345677  & %'* 88889:;<=>?=>@ABCDEFGHIJKLMNOPQQRRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|WXY}~cegqrqrenummapmap-0.2.0Data.EnumMapMap.StrictData.EnumMapSetData.EnumMapMap.LazyData.EnumMapMap.BaseData EnumMapSetData.EnumMapSet.Base emptySubTreesjoinKey unsafeJoinKeyemptynullsizememberaltermap mapWithKeyfoldr foldrWithKeytoListfromListelemskeyskeysSetunionunions unionWith unionWithKey differencedifferenceWithdifferenceWithKey intersectionintersectionWithintersectionWithKeytoStoK singletonlookupinsert insertWith insertWithKeydeletesplitKey:&d1d2d3d4d5d6d7d8d9d10SK EnumMapMapbaseGHC.EnumEnumghc-prim GHC.TypesIntTrue removeEmptiesalter_EMM mergeWithKey'IsKeyemptySubTrees_equalnequalHasSKeySkeySubKeyResultPlusIsSplitHeadTailNZMaskPrefixKeyNatNilTipBin insertWith_ mapWithKey_ foldrWithKey_equalEnequalE natFromInt intFromNatshiftRLshiftLLjoinjoinDbinbinDtipzeronomatchmatchmaskmaskWshorter branchMaskhighestBitMask foldlStrict$fNFDataEnumMapMap$fShowEnumMapMap$fMonoidEnumMapMap$fFunctorEnumMapMap$fEqEMM$fEqEnumMapMap $fIsKey:& $fHasSKey:& $fSubKey:&:&v $fIsSplit:&NKCCEMSBitMap insertSubinsertBMdeleteBM suffixBitMask prefixBitMaskprefixOfsuffixOfbitmapOfSuffixbitmapOfbitcountindexOfTheOnlyBit lowestBitMaskrevNat foldrBits $fSubKeySS() $fSubKeyS:&() $fHasSKeyS$fIsKeySKSClookup_insert_insertWKdelete_ $fSubKeyKKv $fSubKeyK:&v $fIsSplit:&Z $fHasSKeyK$fIsKeyK