!HM:}      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Ziyang Liu <free@cofree.io>Safe2HPVAmulti-containersO(1). The empty multimap. size empty === 0multi-containersO(1)#. A multimap with a single element. Dsingleton 1 'a' === fromList [(1, 'a')] size (singleton 1 'a') === 1multi-containers O(n*log n) where nT is the length of the input list. Build a multimap from a list of key/value pairs. (fromList ([] :: [(Int, Char)]) === emptymulti-containersO(1).multi-containersO(k)N. A key is retained only if it is associated with a non-empty list of values. bfromMap' (Map.fromList [(1, "ab"), (2, ""), (3, "c")]) === fromList [(1, 'a'), (1, 'b'), (3, 'c')]multi-containersO(log k)h. If the key exists in the multimap, the new value will be prepended to the list of values for the key. insert 1 'a' empty === singleton 1 'a' insert 1 'a' (fromList [(2, 'b'), (2, 'c')]) === fromList [(1, 'a'), (2, 'b'), (2, 'c')] insert 1 'a' (fromList [(1, 'b'), (2, 'c')]) === fromList [(1, 'a'), (1, 'b'), (2, 'c')]multi-containersO(log k)/. Delete a key and all its values from the map. Fdelete 1 (fromList [(1, 'a'), (1, 'b'), (2, 'c')]) === singleton 2 'c'multi-containers O(m*log k)O. Remove the first occurrence of the value associated with the key, if exists. +deleteWithValue 1 'c' (fromList [(1, 'a'), (1, 'b'), (2, 'c')]) === fromList [(1, 'a'), (1, 'b'), (2, 'c')] deleteWithValue 1 'c' (fromList [(1, 'a'), (1, 'b'), (2, 'c'), (1, 'c')]) === fromList [(1, 'a'), (1, 'b'), (2, 'c')] deleteWithValue 1 'c' (fromList [(2, 'c'), (1, 'c')]) === singleton 2 'c' multi-containersO(log k). Remove the first value associated with the key. If the key is associated with a single value, the key will be removed from the multimap. deleteOne 1 (fromList [(1, 'a'), (1, 'b'), (2, 'c')]) === fromList [(1, 'b'), (2, 'c')] deleteOne 1 (fromList [(2, 'c'), (1, 'c')]) === singleton 2 'c' multi-containers O(m*log k), assuming the function a -> a takes O(1).. Update values at a specific key, if exists. hadjust ("new " ++) 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"new a"),(1,"new b"),(2,"c")] multi-containers O(m*log k), assuming the function  k -> a -> a takes O(1).. Update values at a specific key, if exists. adjustWithKey (\k x -> show k ++ ":new " ++ x) 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"1:new a"),(1,"1:new b"),(2,"c")] multi-containers O(m*log k), assuming the function a ->  a takes O(1). The expression (  f k map) updates the values at key k, if exists. If f returns # for a value, the value is deleted. let f x = if x == "a" then Just "new a" else Nothing in do update f 1 (fromList [(1,"a"),(1, "b"),(2,"c")]) === fromList [(1,"new a"),(2, "c")] update f 1 (fromList [(1,"b"),(1, "b"),(2,"c")]) === singleton 2 "c" multi-containersO(log k), assuming the function  a -> [a] takes O(1). The expression (  f k map) updates the values at key k, if exists. If f returns , the key is deleted. update' NonEmpty.tail 1 (fromList [(1, "a"), (1, "b"), (2, "c")]) === fromList [(1, "b"), (2, "c")] update' NonEmpty.tail 1 (fromList [(1, "a"), (2, "b")]) === singleton 2 "b"multi-containers O(m*log k), assuming the function  k -> a ->  a takes O(1). The expression ( f k map) updates the values at key k, if exists. If f returns # for a value, the value is deleted. let f k x = if x == "a" then Just (show k ++ ":new a") else Nothing in do updateWithKey f 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"1:new a"),(2,"c")] updateWithKey f 1 (fromList [(1,"b"),(1,"b"),(2,"c")]) === singleton 2 "c"multi-containersO(log k), assuming the function k ->  a -> [a] takes O(1). The expression (  f k map) updates the values at key k, if exists. If f returns , the key is deleted.  let f k xs = if NonEmpty.length xs == 1 then (show k : NonEmpty.toList xs) else [] in do updateWithKey' f 1 (fromList [(1, "a"), (1, "b"), (2, "c")]) === singleton 2 "c" updateWithKey' f 1 (fromList [(1, "a"), (2, "b"), (2, "c")]) === fromList [(1, "1"), (1, "a"), (2, "b"), (2, "c")]multi-containersO(log k), assuming the function  [a] -> [a] takes O(1). The expression ( f k map$) alters the values at k, if exists. clet (f, g) = (const [], ('c':)) in do alter f 1 (fromList [(1, 'a'), (2, 'b')]) === singleton 2 'b' alter f 3 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'a'), (2, 'b')] alter g 1 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'c'), (1, 'a'), (2, 'b')] alter g 3 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'a'), (2, 'b'), (3, 'c')]multi-containersO(log k), assuming the function k -> [a] -> [a] takes O(1). The expression ( f k map$) alters the values at k, if exists. let (f, g) = (const (const []), (:) . show) in do alterWithKey f 1 (fromList [(1, "a"), (2, "b")]) === singleton 2 "b" alterWithKey f 3 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "a"), (2, "b")] alterWithKey g 1 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "1"), (1, "a"), (2, "b")] alterWithKey g 3 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "a"), (2, "b"), (3, "3")]multi-containersO(log k)`. Lookup the values at a key in the map. It returns an empty list if the key is not in the map.multi-containersO(log k)`. Lookup the values at a key in the map. It returns an empty list if the key is not in the map. gfromList [(3, 'a'), (5, 'b'), (3, 'c')] ! 3 === "ac" fromList [(3, 'a'), (5, 'b'), (3, 'c')] ! 2 === []multi-containersO(log k)!. Is the key a member of the map?\A key is a member of the map if and only if there is at least one value associated with it. |member 1 (fromList [(1, 'a'), (2, 'b'), (2, 'c')]) === True member 1 (deleteOne 1 (fromList [(2, 'c'), (1, 'c')])) === Falsemulti-containersO(log k)%. Is the key not a member of the map?\A key is a member of the map if and only if there is at least one value associated with it. notMember 1 (fromList [(1, 'a'), (2, 'b'), (2, 'c')]) === False notMember 1 (deleteOne 1 (fromList [(2, 'c'), (1, 'c')])) === Truemulti-containersO(1). Is the multimap empty? PData.Multimap.null empty === True Data.Multimap.null (singleton 1 'a') === Falsemulti-containersO(1). Is the multimap non-empty? :notNull empty === False notNull (singleton 1 'a') === Truemulti-containers(The total number of values for all keys.sizeG is evaluated lazily. Forcing the size for the first time takes up to O(n) and subsequent forces take O(1). bsize empty === 0 size (singleton 1 'a') === 1 size (fromList [(1, 'a'), (2, 'b'), (2, 'c')]) === 3multi-containers=Union two multimaps, concatenating values for duplicate keys. union (fromList [(1,'a'),(2,'b'),(2,'c')]) (fromList [(1,'d'),(2,'b')]) === fromList [(1,'a'),(1,'d'),(2,'b'),(2,'c'),(2,'b')]multi-containersEUnion a number of multimaps, concatenating values for duplicate keys. unions [fromList [(1,'a'),(2,'b'),(2,'c')], fromList [(1,'d'),(2,'b')]] === fromList [(1,'a'),(1,'d'),(2,'b'),(2,'c'),(2,'b')]multi-containersDifference of two multimaps.If a key exists in the first multimap but not the second, it remains unchanged in the result. If a key exists in both multimaps, a list difference is performed on their values, i.e., the first occurrence of each value in the second multimap is removed from the first multimap. difference (fromList [(1,'a'),(2,'b'),(2,'c'),(2,'b')]) (fromList [(1,'d'),(2,'b'),(2,'a')]) === fromList [(1,'a'), (2,'c'), (2,'b')]multi-containersO(n), assuming the function a -> b takes O(1)-. Map a function over all values in the map. iData.Multimap.map (++ "x") (fromList [(1,"a"),(1,"a"),(2,"b")]) === fromList [(1,"ax"),(1,"ax"),(2,"bx")]multi-containersO(n), assuming the function  k -> a -> b takes O(1)6. Map a function over all key/value pairs in the map. ymapWithKey (\k x -> show k ++ ":" ++ x) (fromList [(1,"a"),(1,"a"),(2,"b")]) === fromList [(1,"1:a"),(1,"1:a"),(2,"2:b")]multi-containers1Traverse key/value pairs and collect the results.  let f k a = if odd k then Just (succ a) else Nothing in do traverseWithKey f (fromList [(1, 'a'), (1, 'b'), (3, 'b'), (3, 'c')]) === Just (fromList [(1, 'b'), (1, 'c'), (3, 'c'), (3, 'd')]) traverseWithKey f (fromList [(1, 'a'), (1, 'b'), (2, 'b')]) === Nothingmulti-containers)Traverse key/value pairs and collect the  results. multi-containersO(n)P. Fold the values in the map using the given right-associative binary operator. ]Data.Multimap.foldr ((+) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11!multi-containersO(n)O. Fold the values in the map using the given left-associative binary operator. iData.Multimap.foldl (\len -> (+ len) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11"multi-containersO(n)Y. Fold the key/value pairs in the map using the given right-associative binary operator. wfoldrWithKey (\k a len -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15#multi-containersO(n)X. Fold the key/value pairs in the map using the given left-associative binary operator. wfoldlWithKey (\len k a -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15$multi-containersO(n). A strict version of  . Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. ^Data.Multimap.foldr' ((+) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11%multi-containersO(n). A strict version of !. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. jData.Multimap.foldl' (\len -> (+ len) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11&multi-containersO(n). A strict version of ". Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. xfoldrWithKey' (\k a len -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15'multi-containersO(n). A strict version of #. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. xfoldlWithKey' (\len k a -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15(multi-containersO(n)=. Fold the key/value pairs in the map using the given monoid. efoldMapWithKey (\k x -> show k ++ ":" ++ x) (fromList [(1, "a"), (1, "a"), (2, "b")]) === "1:a1:a2:b")multi-containersO(n)H. Return all elements of the multimap in ascending order of their keys. nelems (fromList [(2, 'a'), (1, 'b'), (3, 'c'), (1, 'b')]) === "bbac" elems (empty :: Multimap Int Char) === []*multi-containersO(k)5. Return all keys of the multimap in ascending order. mkeys (fromList [(2, 'a'), (1, 'b'), (3, 'c'), (1, 'b')]) === [1,2,3] keys (empty :: Multimap Int Char) === []+multi-containersO(k)&. The set of all keys of the multimap. keysSet (fromList [(2, 'a'), (1, 'b'), (3, 'c'), (1, 'b')]) === Set.fromList [1,2,3] keysSet (empty :: Multimap Int Char) === Set.empty,multi-containers An alias for .. Yassocs (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(1,'b'),(1,'a'),(2,'a'),(3,'c')]-multi-containers4Convert the multimap into a list of key/value pairs. YtoList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(1,'b'),(1,'a'),(2,'a'),(3,'c')].multi-containersPConvert the multimap into a list of key/value pairs in ascending order of keys. \toAscList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(1,'b'),(1,'a'),(2,'a'),(3,'c')]/multi-containersQConvert the multimap into a list of key/value pairs in descending order of keys. ]toDescList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(3,'c'),(2,'a'),(1,'b'),(1,'a')]0multi-containerslConvert the multimap into a list of key/value pairs, in a breadth-first manner, in ascending order of keys. toAscListBF (fromList [("Foo",1),("Foo",2),("Foo",3),("Bar",4),("Bar",5),("Baz",6)]) === [("Bar",4),("Baz",6),("Foo",1),("Bar",5),("Foo",2),("Foo",3)]1multi-containersmConvert the multimap into a list of key/value pairs, in a breadth-first manner, in descending order of keys. toDescListBF (fromList [("Foo",1),("Foo",2),("Foo",3),("Bar",4),("Bar",5),("Baz",6)]) === [("Foo",1),("Baz",6),("Bar",4),("Foo",2),("Bar",5),("Foo",3)]2multi-containersO(1)*. Convert the multimap into a regular map.3multi-containersO(n)(, assuming the predicate function takes O(1)0. Retain all values that satisfy the predicate. Data.Multimap.filter (> 'a') (fromList [(1,'a'),(1,'b'),(2,'a')]) === singleton 1 'b' Data.Multimap.filter (< 'a') (fromList [(1,'a'),(1,'b'),(2,'a')]) === empty4multi-containersO(k)(, assuming the predicate function takes O(1).. Retain all keys that satisfy the predicate. GfilterKey even (fromList [(1,'a'),(1,'b'),(2,'a')]) === singleton 2 'a'5multi-containersO(n)(, assuming the predicate function takes O(1)9. Retain all key/value pairs that satisfy the predicate. jfilterWithKey (\k a -> even k && a > 'a') (fromList [(1,'a'),(1,'b'),(2,'a'),(2,'b')]) === singleton 2 'b'6multi-containers Generalized 3. let f a | a > 'b' = Just True | a < 'b' = Just False | a == 'b' = Nothing in do filterM f (fromList [(1,'a'),(1,'b'),(2,'a'),(2,'c')]) === Nothing filterM f (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === Just (fromList [(1,'c'),(2,'c')])7multi-containers Generalized 5. .let f k a | even k && a > 'b' = Just True | odd k && a < 'b' = Just False | otherwise = Nothing in do filterWithKeyM f (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === Nothing filterWithKeyM f (fromList [(1,'a'),(1,'a'),(2,'c'),(2,'c')]) === Just (fromList [(2,'c'),(2,'c')])8multi-containersO(n), assuming the function a ->  b takes O(1). Map values and collect the  results. mapMaybe (\a -> if a == "a" then Just "new a" else Nothing) (fromList [(1,"a"),(1,"b"),(2,"a"),(2,"c")]) === fromList [(1,"new a"),(2,"new a")]9multi-containersO(n), assuming the function  k -> a ->  b takes O(1)'. Map key/value pairs and collect the  results. mapMaybeWithKey (\k a -> if k > 1 && a == "a" then Just "new a" else Nothing) (fromList [(1,"a"),(1,"b"),(2,"a"),(2,"c")]) === singleton 2 "new a":multi-containersO(n), assuming the function a ->  b c takes O(1). Map values and separate the  and  results. mapEither (\a -> if a < 'b' then Left a else Right a) (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === (fromList [(1,'a'),(2,'a')],fromList [(1,'c'),(2,'c')]);multi-containersO(n), assuming the function  k -> a ->  b c takes O(1)(. Map key/value pairs and separate the  and  results. mapEitherWithKey (\k a -> if even k && a < 'b' then Left a else Right a) (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === (fromList [(2,'a')],fromList [(1,'a'),(1,'c'),(2,'c')])<multi-containersO(log n)=. Return the smallest key and the associated values. Returns  if the map is empty. lookupMin (fromList [(1,'a'),(1,'c'),(2,'c')]) === Just (1, NonEmpty.fromList "ac") lookupMin (empty :: Multimap Int Char) === Nothing=multi-containersO(log n)<. Return the largest key and the associated values. Returns  if the map is empty. lookupMax (fromList [(1,'a'),(1,'c'),(2,'c')]) === Just (2, NonEmpty.fromList "c") lookupMax (empty :: Multimap Int Char) === Nothing>multi-containersO(log n)Z. Return the largest key smaller than the given one, and the associated values, if exist. lookupLT 1 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupLT 4 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, NonEmpty.fromList "bc")?multi-containersO(log n)Z. Return the smallest key larger than the given one, and the associated values, if exist. lookupGT 5 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupGT 2 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, NonEmpty.fromList "bc")@multi-containersO(log n)f. Return the largest key smaller than or equal to the given one, and the associated values, if exist. lookupLE 0 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupLE 1 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (1, NonEmpty.fromList "a") lookupLE 4 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, NonEmpty.fromList "bc")Amulti-containersO(log n)f. Return the smallest key larger than or equal to the given one, and the associated values, if exist. lookupGE 6 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupGE 5 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (5, NonEmpty.fromList "c") lookupGE 2 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, NonEmpty.fromList "bc")B  !"#$%&'()*+,-./0123456789:;<=>?@AB  !"#($%&')*,+-./0123546789:;<=>?@A9 Ziyang Liu <free@cofree.io>Safe2HPV;Tmulti-containersO(1). The empty multimap. size empty === 0Umulti-containersO(1)#. A multimap with a single element. Dsingleton 1 'a' === fromList [(1, 'a')] size (singleton 1 'a') === 1Vmulti-containers O(n*log n) where nT is the length of the input list. Build a multimap from a list of key/value pairs. rfromList ([] :: [(Int, Char)]) === empty fromList [(1, 'b'), (2, 'a'), (1, 'b')] === fromList [(1, 'b'), (2, 'a')]Wmulti-containersO(k)M. A key is retained only if it is associated with a non-empty set of values.Xmulti-containersO(log m * log k). If the key exists in the multimap, the new value will be inserted into the set of values for the key. It is a no-op if the value already exists in the set. insert 1 'a' empty === singleton 1 'a' insert 1 'a' (fromList [(1, 'b'), (2, 'a')]) === fromList [(1, 'a'), (1, 'b'), (2, 'a')] insert 1 'a' (fromList [(1, 'a'), (2, 'c')]) === fromList [(1, 'a'), (2, 'c')]Ymulti-containersO(log k)/. Delete a key and all its values from the map. Adelete 1 (fromList [(1,'a'),(1,'b'),(2,'c')]) === singleton 2 'c'Zmulti-containersO(log m * log k)O. Remove the first occurrence of the value associated with the key, if exists. deleteWithValue 1 'c' (fromList [(1,'a'),(1,'b'),(2,'c')]) === fromList [(1,'a'),(1,'b'),(2,'c')] deleteWithValue 1 'c' (fromList [(2,'c'),(1,'c')]) === singleton 2 'c'[multi-containersO(log m * log k)?. Remove the maximal value associated with the key, if exists. deleteMax 3 (fromList [(1,'a'),(1,'b'),(2,'c')]) === fromList [(1,'a'),(1,'b'),(2,'c')] deleteMax 1 (fromList [(1,'a'),(1,'b'),(2,'c')]) === fromList [(1,'a'),(2,'c')]\multi-containersO(log m * log k)?. Remove the minimal value associated with the key, if exists. deleteMin 3 (fromList [(1,'a'),(1,'b'),(2,'c')]) === fromList [(1,'a'),(1,'b'),(2,'c')] deleteMin 1 (fromList [(1,'a'),(1,'b'),(2,'c')]) === fromList [(1,'b'),(2,'c')]]multi-containersO(m * log m * log k), assuming the function a -> a takes O(1).. Update values at a specific key, if exists.LSince values are sets, the result may be smaller than the original multimap. adjust ("new " ++) 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"new a"),(1,"new b"),(2,"c")] adjust (const "z") 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"z"),(2,"c")]^multi-containersO(m * log m * log k), assuming the function  k -> a -> a takes O(1).. Update values at a specific key, if exists.LSince values are sets, the result may be smaller than the original multimap. adjustWithKey (\k x -> show k ++ ":new " ++ x) 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"1:new a"),(1,"1:new b"),(2,"c")]_multi-containersO(m * log m * log k), assuming the function a ->  a takes O(1). The expression (_ f k map) updates the values at key k, if exists. If f returns $ for a value, the value is deleted. let f x = if x == "a" then Just "new a" else Nothing in do update f 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"new a"),(2, "c")] update f 1 (fromList [(1,"b"),(1,"c"),(2,"c")]) === singleton 2 "c"`multi-containersO(m * log m * log k), assuming the function  k -> a ->  a takes O(1). The expression (` f k map) updates the values at key k, if exists. If f returns $ for a value, the value is deleted. let f k x = if x == "a" then Just (show k ++ ":new a") else Nothing in do updateWithKey f 1 (fromList [(1,"a"),(1,"b"),(2,"c")]) === fromList [(1,"1:new a"),(2,"c")] updateWithKey f 1 (fromList [(1,"b"),(1,"c"),(2,"c")]) === singleton 2 "c"amulti-containersO(log k), assuming the function  a ->  a takes O(1). The expression (a f k map$) alters the values at k, if exists. let (f, g) = (const Set.empty, Set.insert 'c') in do alter f 1 (fromList [(1, 'a'), (2, 'b')]) === singleton 2 'b' alter f 3 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'a'), (2, 'b')] alter g 1 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'c'), (1, 'a'), (2, 'b')] alter g 1 (fromList [(1, 'c'), (2, 'b')]) === fromList [(1, 'c'), (2, 'b')] alter g 3 (fromList [(1, 'a'), (2, 'b')]) === fromList [(1, 'a'), (2, 'b'), (3, 'c')]bmulti-containersO(log k), assuming the function k ->  a ->  a takes O(1). The expression (b f k map$) alters the values at k, if exists. let (f, g) = (const (const Set.empty), Set.insert . show) in do alterWithKey f 1 (fromList [(1, "a"), (2, "b")]) === singleton 2 "b" alterWithKey f 3 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "a"), (2, "b")] alterWithKey g 1 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "1"), (1, "a"), (2, "b")] alterWithKey g 3 (fromList [(1, "a"), (2, "b")]) === fromList [(1, "a"), (2, "b"), (3, "3")]cmulti-containersO(log k)_. Lookup the values at a key in the map. It returns an empty set if the key is not in the map.dmulti-containersO(log k)_. Lookup the values at a key in the map. It returns an empty set if the key is not in the map. {fromList [(3, 'a'), (5, 'b'), (3, 'c')] ! 3 === Set.fromList "ac" fromList [(3, 'a'), (5, 'b'), (3, 'c')] ! 2 === Set.emptyemulti-containersO(log k)!. Is the key a member of the map?\A key is a member of the map if and only if there is at least one value associated with it. |member 1 (fromList [(1, 'a'), (2, 'b'), (2, 'c')]) === True member 1 (deleteMax 1 (fromList [(2, 'c'), (1, 'c')])) === Falsefmulti-containersO(log k)%. Is the key not a member of the map?\A key is a member of the map if and only if there is at least one value associated with it. notMember 1 (fromList [(1, 'a'), (2, 'b'), (2, 'c')]) === False notMember 1 (deleteMin 1 (fromList [(2, 'c'), (1, 'c')])) === Truegmulti-containersO(1). Is the multimap empty? XData.Multimap.Set.null empty === True Data.Multimap.Set.null (singleton 1 'a') === Falsehmulti-containersO(1). Is the multimap non-empty? :notNull empty === False notNull (singleton 1 'a') === Trueimulti-containers(The total number of values for all keys.sizeG is evaluated lazily. Forcing the size for the first time takes up to O(k) and subsequent forces take O(1). lsize empty === 0 size (singleton 1 'a') === 1 size (fromList [(1, 'a'), (2, 'b'), (2, 'c'), (2, 'b')]) === 3jmulti-containers8Union two multimaps, unioning values for duplicate keys. xunion (fromList [(1,'a'),(2,'b'),(2,'c')]) (fromList [(1,'d'),(2,'b')]) === fromList [(1,'a'),(1,'d'),(2,'b'),(2,'c')]kmulti-containers@Union a number of multimaps, unioning values for duplicate keys. xunions [fromList [(1,'a'),(2,'b'),(2,'c')], fromList [(1,'d'),(2,'b')]] === fromList [(1,'a'),(1,'d'),(2,'b'),(2,'c')]lmulti-containersDifference of two multimaps.If a key exists in the first multimap but not the second, it remains unchanged in the result. If a key exists in both multimaps, a set difference is performed on their values. udifference (fromList [(1,'a'),(2,'b'),(2,'c')]) (fromList [(1,'d'),(2,'b'),(2,'a')]) === fromList [(1,'a'),(2,'c')]mmulti-containers O(n * log m), assuming the function a -> b takes O(1)-. Map a function over all values in the map.LSince values are sets, the result may be smaller than the original multimap. Data.Multimap.Set.map (++ "x") (fromList [(1,"a"),(2,"b")]) === fromList [(1,"ax"),(2,"bx")] Data.Multimap.Set.map (const "c") (fromList [(1,"a"),(1,"b"),(2,"b")]) === fromList [(1,"c"),(2,"c")]nmulti-containers O(n * log m), assuming the function  k -> a -> b takes O(1)-. Map a function over all values in the map.LSince values are sets, the result may be smaller than the original multimap. gmapWithKey (\k x -> show k ++ ":" ++ x) (fromList [(1,"a"),(2,"b")]) === fromList [(1,"1:a"),(2,"2:b")]omulti-containersO(n)P. Fold the values in the map using the given right-associative binary operator. aData.Multimap.Set.foldr ((+) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11pmulti-containersO(n)O. Fold the values in the map using the given left-associative binary operator. mData.Multimap.Set.foldl (\len -> (+ len) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11qmulti-containersO(n)Y. Fold the key/value pairs in the map using the given right-associative binary operator. wfoldrWithKey (\k a len -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15rmulti-containersO(n)X. Fold the key/value pairs in the map using the given left-associative binary operator. wfoldlWithKey (\len k a -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15smulti-containersO(n). A strict version of o. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. bData.Multimap.Set.foldr' ((+) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11tmulti-containersO(n). A strict version of p. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. nData.Multimap.Set.foldl' (\len -> (+ len) . length) 0 (fromList [(1, "hello"), (1, "world"), (2, "!")]) === 11umulti-containersO(n). A strict version of q. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. xfoldrWithKey' (\k a len -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15vmulti-containersO(n). A strict version of r. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. xfoldlWithKey' (\len k a -> length (show k) + length a + len) 0 (fromList [(1, "hello"), (1, "world"), (20, "!")]) === 15wmulti-containersO(n)=. Fold the key/value pairs in the map using the given monoid. efoldMapWithKey (\k x -> show k ++ ":" ++ x) (fromList [(1, "a"), (1, "c"), (2, "b")]) === "1:a1:c2:b"xmulti-containersO(n)x. Return all elements of the multimap in ascending order of their keys. Elements of each key appear in ascending order. relems (fromList [(2,'a'),(1,'b'),(3,'d'),(3,'c'),(1,'b')]) === "bacd" elems (empty :: SetMultimap Int Char) === []ymulti-containersO(k)5. Return all keys of the multimap in ascending order. ikeys (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'b')]) === [1,2,3] keys (empty :: SetMultimap Int Char) === []zmulti-containersO(k)&. The set of all keys of the multimap. keysSet (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'b')]) === Set.fromList [1,2,3] keysSet (empty :: SetMultimap Int Char) === Set.empty{multi-containers An alias for }.|multi-containers4Convert the multimap into a list of key/value pairs. YtoList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(1,'a'),(1,'b'),(2,'a'),(3,'c')]}multi-containersConvert the multimap into a list of key/value pairs in ascending order of keys. Elements of each key appear in ascending order. \toAscList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(1,'a'),(1,'b'),(2,'a'),(3,'c')]~multi-containersConvert the multimap into a list of key/value pairs in descending order of keys. Elements of each key appear in descending order. ]toDescList (fromList [(2,'a'),(1,'b'),(3,'c'),(1,'a')]) === [(3,'c'),(2,'a'),(1,'b'),(1,'a')]multi-containersO(1)*. Convert the multimap into a regular map.multi-containersO(n)(, assuming the predicate function takes O(1)q. Retain all values that satisfy the predicate. A key is removed if none of its values satisfies the predicate. Data.Multimap.Set.filter (> 'a') (fromList [(1,'a'),(1,'b'),(2,'a')]) === singleton 1 'b' Data.Multimap.Set.filter (< 'a') (fromList [(1,'a'),(1,'b'),(2,'a')]) === emptymulti-containersO(k)(, assuming the predicate function takes O(1).. Retain all keys that satisfy the predicate.multi-containersO(n)(, assuming the predicate function takes O(1)z. Retain all key/value pairs that satisfy the predicate. A key is removed if none of its values satisfies the predicate. jfilterWithKey (\k a -> even k && a > 'a') (fromList [(1,'a'),(1,'b'),(2,'a'),(2,'b')]) === singleton 2 'b'multi-containers Generalized . let f a | a > 'b' = Just True | a < 'b' = Just False | a == 'b' = Nothing in do filterM f (fromList [(1,'a'),(1,'b'),(2,'a'),(2,'c')]) === Nothing filterM f (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === Just (fromList [(1,'c'),(2,'c')])multi-containers Generalized . | Generalized . .let f k a | even k && a > 'b' = Just True | odd k && a < 'b' = Just False | otherwise = Nothing in do filterWithKeyM f (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === Nothing filterWithKeyM f (fromList [(1,'a'),(3,'a'),(2,'c'),(4,'c')]) === Just (fromList [(2,'c'),(4,'c')])multi-containers O(n * log m), assuming the function a ->  b takes O(1). Map values and collect the  results. mapMaybe (\a -> if a == "a" then Just "new a" else Nothing) (fromList [(1,"a"),(1,"b"),(2,"a"),(2,"c")]) === fromList [(1,"new a"),(2,"new a")]multi-containers O(n * log m), assuming the function  k -> a ->  b takes O(1)'. Map key/value pairs and collect the  results. mapMaybeWithKey (\k a -> if k > 1 && a == "a" then Just "new a" else Nothing) (fromList [(1,"a"),(1,"b"),(2,"a"),(2,"c")]) === singleton 2 "new a"multi-containers O(n * log m), assuming the function a ->  b c takes O(1). Map values and separate the  and  results. mapEither (\a -> if a < 'b' then Left a else Right a) (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === (fromList [(1,'a'),(2,'a')],fromList [(1,'c'),(2,'c')])multi-containers O(n * log m), assuming the function  k -> a ->  b c takes O(1)(. Map key/value pairs and separate the  and  results. mapEitherWithKey (\k a -> if even k && a < 'b' then Left a else Right a) (fromList [(1,'a'),(1,'c'),(2,'a'),(2,'c')]) === (fromList [(2,'a')],fromList [(1,'a'),(1,'c'),(2,'c')])multi-containersO(log n)=. Return the smallest key and the associated values. Returns  if the map is empty. lookupMin (fromList [(1,'a'),(1,'c'),(2,'c')]) === Just (1, Set.fromList "ac") lookupMin (empty :: SetMultimap Int Char) === Nothingmulti-containersO(log n)<. Return the largest key and the associated values. Returns  if the map is empty. lookupMax (fromList [(1,'a'),(1,'c'),(2,'c')]) === Just (2, Set.fromList "c") lookupMax (empty :: SetMultimap Int Char) === Nothingmulti-containersO(log n)Z. Return the largest key smaller than the given one, and the associated values, if exist. lookupLT 1 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupLT 4 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, Set.fromList "bc")multi-containersO(log n)Z. Return the smallest key larger than the given one, and the associated values, if exist. lookupGT 5 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupGT 2 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, Set.fromList "bc")multi-containersO(log n)f. Return the largest key smaller than or equal to the given one, and the associated values, if exist. lookupLE 0 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupLE 1 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (1, Set.fromList "a") lookupLE 4 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, Set.fromList "bc")multi-containersO(log n)f. Return the smallest key larger than or equal to the given one, and the associated values, if exist. lookupGE 6 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Nothing lookupGE 5 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (5, Set.fromList "c") lookupGE 2 (fromList [(1,'a'),(3,'b'),(3,'c'),(5,'c')]) === Just (3, Set.fromList "bc")<STUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~<STUWVXYZ[\]^_`abcdefghijklmnopqrwstuvxy{z|}~d9 Ziyang Liu <free@cofree.io>Safe2HV7Cmulti-containersO(1). The empty table. size empty === 0multi-containersO(1) . A table with a single element. Osingleton 1 'a' "a" === fromList [(1,'a',"a")] size (singleton 1 'a' "a") === 1multi-containers-Build a table from a list of key/value pairs. 0fromList ([] :: [(Int, Char, String)]) === emptymulti-containersBuild a table from a row map. fromRowMap (Map.fromList [(1, Map.fromList [('a',"b"),('b',"c")]), (2, Map.fromList [('a',"d")])]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]multi-containers Build a table from a column map. fromColumnMap (Map.fromList [(1, Map.fromList [('a',"b"),('b',"c")]), (2, Map.fromList [('a',"d")])]) === fromList [('a',1,"b"),('a',2,"d"),('b',1,"c")]multi-containersFlip the row and column keys. mtranspose (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [('a',1,"b"),('a',2,"d"),('b',1,"c")]multi-containersO(log k). Associate with value with the row key and the column key. If the table already contains a value for those keys, the value is replaced.  insert 1 'a' "a" empty === singleton 1 'a' "a" insert 1 'a' "a" (fromList [(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"a"),(1,'b',"c"),(2,'a',"d")] insert 1 'a' "a" (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"a"),(1,'b',"c"),(2,'a',"d")]multi-containersO(log k)2. Remove the value associated with the given keys. delete 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'b',"c"),(2,'a',"d")] delete 1 'a' (fromList [(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'b',"c"),(2,'a',"d")]multi-containersRemove an entire row. deleteRow 1 (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 2 'a' "d" deleteRow 3 (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]multi-containersRemove an entire column. deleteColumn 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 1 'b' "c" deleteColumn 'z' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]multi-containersO(log k), assuming the function a -> a takes O(1)D. Update the value at a specific row key and column key, if exists. adjust ("new " ++) 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"new b"),(1,'b',"c"),(2,'a',"d")]multi-containersO(log k), assuming the function r -> c -> a -> a takes O(1)D. Update the value at a specific row key and column key, if exists. adjustWithKeys (\r c x -> show r ++ ":" ++ show c ++ ":new " ++ x) 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === fromList [(1,'a',"1:'a':new b"),(1,'b',"c"),(2,'a',"d")]multi-containersO(log k), assuming the function a ->  a takes O(1). The expression ( f r c tableE) updates the value at the given row and column keys, if exists. If f returns >, the value associated with those keys, if exists is deleted. Llet f x = if x == "b" then Just "new b" else Nothing in do update f 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"new b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] update f 1 'a' (fromList [(1,'a',"a"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]multi-containersO(log k), assuming the function r -> c -> a ->  a takes O(1). The expression ( f r c tableE) updates the value at the given row and column keys, if exists. If f returns >, the value associated with those keys, if exists is deleted. let f r c x = if x == "b" then Just (show r ++ ":" ++ show c ++ ":new b") else Nothing in do updateWithKeys f 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"1:'a':new b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] updateWithKeys f 1 'a' (fromList [(1,'a',"a"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]multi-containersO(log k), assuming the function  a ->  a takes O(1). The expression ( f r c tableu) alters the value at the given row and column keys, if exists. It can be used to insert, delete or update a value. #let (f,g,h) = (const Nothing, const (Just "hello"), fmap ('z':)) in do alter f 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alter f 4 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alter f 2 'b' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alter g 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"hello"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alter g 4 'e' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c"),(4,'e',"hello")] alter h 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"zb"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alter h 2 'b' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]multi-containersO(log k), assuming the function  r -> c ->  a ->  a takes O(1). The expression ( f r c tableu) alters the value at the given row and column keys, if exists. It can be used to insert, delete or update a value. 7let (f,g) = (\_ _ _ -> Nothing, \r c -> fmap ((show r ++ ":" ++ show c ++ ":") ++)) in do alterWithKeys f 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alterWithKeys f 4 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alterWithKeys f 2 'b' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alterWithKeys g 1 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"1:'a':b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")] alterWithKeys g 2 'b' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(3,'a',"c")]multi-containersO(log k);. Lookup the values at a row key and column key in the map.multi-containersO(log k);. Lookup the values at a row key and column key in the map. fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")] !? (1,'a') === Just "b" fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")] !? (1,'c') === Nothingmulti-containersO(log k)C. Lookup the values at a row key and column key in the map. Calls  if the value does not exist. @fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")] ! (1,'a') === "b"multi-containersO(log k)B. Is there a value associated with the given row and column keys? hasCell (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (1,'a') === True hasCell (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (1,'c') === Falsemulti-containersO(log r)F. Is there a row with the given row key that has at least one value? hasRow (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) 1 === True hasRow (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) 3 === Falsemulti-containersO(log c)K. Is there a column with the given column key that has at least one value? hasColumn (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) 'a' === True hasColumn (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) 'c' === Falsemulti-containersO(1). Is the table empty? `Data.Multimap.Table.null empty === True Data.Multimap.Table.null (singleton 1 'a' "a") === Falsemulti-containersO(1). Is the table non-empty? >notNull empty === False notNull (singleton 1 'a' "a") === Truemulti-containers7The total number of values for all row and column keys.sizeG is evaluated lazily. Forcing the size for the first time takes up to O(n) and subsequent forces take O(1). msize empty === 0 size (singleton 1 'a' "a") === 1 size (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) === 3multi-containersNUnion two tables, preferring values from the first table upon duplicate keys. union (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]) === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containersYUnion a number of tables, preferring values from the leftmost table upon duplicate keys. unions [fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")], fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]] === fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containers>Union two tables with a combining function for duplicate keys. unionWith (++) (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]) === fromList [(1,'a',"bc"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containers>Union two tables with a combining function for duplicate keys. let f r c a a' = show r ++ ":" ++ show c ++ ":" ++ a ++ "|" ++ a' in do unionWithKeys f (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]) === fromList [(1,'a',"1:'a':b|c"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containersFUnion a number of tables with a combining function for duplicate keys. unionsWith (++) [fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")], fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]] === fromList [(1,'a',"bc"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containersFUnion a number of tables with a combining function for duplicate keys. let f r c a a' = show r ++ ":" ++ show c ++ ":" ++ a ++ "|" ++ a' in do unionsWithKeys f [fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")], fromList [(1,'a',"c"),(2,'b',"d"),(3,'c',"e")]] === fromList [(1,'a',"1:'a':b|c"),(1,'b',"c"),(2,'a',"b"),(2,'b',"d"),(3,'c',"e")]multi-containersDifference of two tables. Return values in the first table whose row and column keys do not have an associated value in the second table. difference (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) (fromList [(1,'a',"c"),(1,'b',"d"),(2,'b',"b")]) === singleton 2 'a' "b"multi-containersO(n), assuming the function a -> b takes O(1)/. Map a function over all values in the table. Data.Multimap.Table.map (++ "x") (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) === fromList [(1,'a',"bx"),(1,'b',"cx"),(2,'a',"bx")]multi-containersO(n), assuming the function r -> c -> a -> b takes O(1)/. Map a function over all values in the table. mapWithKeys (\r c x -> show r ++ ":" ++ show c ++ ":" ++ x) (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) === fromList [(1,'a',"1:'a':b"),(1,'b',"1:'b':c"),(2,'a',"2:'a':b")]multi-containersJTraverse the (row key, column key, value) triples and collect the results. let f r c a = if odd r && c > 'a' then Just (a ++ "x") else Nothing in do traverseWithKeys f (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"b")]) === Nothing traverseWithKeys f (fromList [(1,'b',"b"),(1,'c',"c"),(3,'d',"b")]) === Just (fromList [(1,'b',"bx"),(1,'c',"cx"),(3,'d',"bx")])multi-containersBTraverse the (row key, column key, value) triples and collect the  results.multi-containersO(n)]. Fold the values in the table row by row using the given right-associative binary operator. [Data.Multimap.Table.foldr (:) "" (fromList [(1,'a','b'),(1,'b','c'),(2,'a','d')]) === "bcd"multi-containersO(n)\. Fold the values in the table row by row using the given left-associative binary operator. bData.Multimap.Table.foldl (flip (:)) "" (fromList [(1,'a','b'),(1,'b','c'),(2,'a','d')]) === "dcb"multi-containersO(n)|. Fold the (row key, column key value) triplets in the table row by row using the given right-associative binary operator. let f r c a b = show r ++ ":" ++ show c ++ ":" ++ a ++ "|" ++ b in do foldrWithKeys f "" (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === "1:'a':b|1:'b':c|2:'a':d|"multi-containersO(n)|. Fold the (row key, column key, value) triplets in the table row by row using the given left-associative binary operator. let f a r c b = show r ++ ":" ++ show c ++ ":" ++ b ++ "|" ++ a in do foldlWithKeys f "" (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === "2:'a':d|1:'b':c|1:'a':b|"multi-containersO(n). A strict version of . Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. \Data.Multimap.Table.foldr' (:) "" (fromList [(1,'a','b'),(1,'b','c'),(2,'a','d')]) === "bcd"multi-containersO(n). A strict version of . Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. cData.Multimap.Table.foldl' (flip (:)) "" (fromList [(1,'a','b'),(1,'b','c'),(2,'a','d')]) === "dcb"multi-containersO(n). A strict version of  foldrWithKey. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. let f r c a b = show r ++ ":" ++ show c ++ ":" ++ a ++ "|" ++ b in do foldrWithKeys' f "" (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === "1:'a':b|1:'b':c|2:'a':d|"multi-containersO(n). A strict version of  foldlWithKey. Each application of the operator is evaluated before using the result in the next application. This function is strict in the starting value. let f a r c b = show r ++ ":" ++ show c ++ ":" ++ b ++ "|" ++ a in do foldlWithKeys' f "" (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === "2:'a':d|1:'b':c|1:'a':b|"multi-containersO(n)_. Fold the (row key, column key, value) triplets in the map row by row using the given monoid. let f r c a = show r ++ ":" ++ show c ++ ":" ++ a ++ "|" in do foldMapWithKeys f (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === "1:'a':b|1:'b':c|2:'a':d|"multi-containersO(r)E. Return a mapping from column keys to values for the given row key. row 1 (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.fromList [('a',"b"),('b',"c")] row 3 (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.emptymulti-containersO(c)E. Return a mapping from row keys to values for the given column key. column 'a' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.fromList [(1,"b"),(2,"d")] column 'c' (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.emptymulti-containersBReturn a mapping from row keys to maps from column keys to values. rowMap (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.fromList [(1, Map.fromList [('a',"b"),('b',"c")]),(2, Map.fromList [('a',"d")])]multi-containersBReturn a mapping from column keys to maps from row keys to values. columnMap (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Map.fromList [('a', Map.fromList [(1,"b"),(2,"d")]),('b', Map.fromList [(1,"c")])]multi-containerscReturn, in ascending order, the list of all row keys of that have at least one value in the table. BrowKeys (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [1,2]multi-containersfReturn, in ascending order, the list of all column keys of that have at least one value in the table. IcolumnKeys (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === ['a','b']multi-containersMReturn the set of all row keys of that have at least one value in the table. RrowKeysSet (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Set.fromList [1,2]multi-containersPReturn the set of all column keys of that have at least one value in the table. YcolumnKeysSet (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === Set.fromList ['a','b']multi-containersFConvert the table into a list of (row key, column key, value) triples. atoList (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]multi-containersConvert the table into a list of (row key, column key, value) triples in ascending order of row keys, and ascending order of column keys with a row. gtoRowAscList (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]multi-containersConvert the table into a list of (column key, row key, value) triples in ascending order of column keys, and ascending order of row keys with a column. jtoColumnAscList (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [('a',1,"b"),('a',2,"d"),('b',1,"c")]multi-containersConvert the table into a list of (row key, column key, value) triples in descending order of row keys, and descending order of column keys with a row. htoRowDescList (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [(2,'a',"d"),(1,'b',"c"),(1,'a',"b")]multi-containersConvert the table into a list of (column key, row key, value) triples in descending order of column keys, and descending order of row keys with a column. ktoColumnDescList (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === [('b',1,"c"),('a',2,"d"),('a',1,"b")]multi-containersO(n)(, assuming the predicate function takes O(1)0. Retain all values that satisfy the predicate. Data.Multimap.Table.filter (> "c") (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 2 'a' "d" Data.Multimap.Table.filter (> "d") (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === emptymulti-containersO(r)(, assuming the predicate function takes O(1).. Retain all rows that satisfy the predicate. WfilterRow even (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 2 'a' "d"multi-containersO(c)(, assuming the predicate function takes O(1)1. Retain all columns that satisfy the predicate. ]filterColumn (> 'a') (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 1 'b' "c"multi-containersO(c)(, assuming the predicate function takes O(1)N. Retain all (row key, column key, value) triples that satisfy the predicate. filterWithKeys (\r c a -> odd r && c > 'a' && a > "b") (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 1 'b' "c"multi-containersO(n), assuming the function a ->  b takes O(1). Map values and collect the  results. mapMaybe (\a -> if a == "a" then Just "new a" else Nothing) (fromList [(1,'a',"a"),(1,'b',"c"),(2,'b',"a")]) === fromList [(1,'a',"new a"),(2,'b',"new a")]multi-containersO(n), assuming the function r -> c -> a ->  b takes O(1)<. Map (row key, column key, value) triples and collect the  results. let f r c a = if r == 1 && a == "c" then Just "new c" else Nothing in do mapMaybeWithKeys f (fromList [(1,'a',"b"),(1,'b',"c"),(2,'a',"d")]) === singleton 1 'b' "new c"multi-containersO(n), assuming the function a ->  a1 a2 takes O(1). Map values and separate the  and  results. mapEither (\a -> if a == "a" then Left a else Right a) (fromList [(1,'a',"a"),(1,'b',"c"),(2,'b',"a")]) === (fromList [(1,'a',"a"),(2,'b',"a")],fromList [(1,'b',"c")])multi-containersO(n), assuming the function r -> c -> a ->  a1 a2 takes O(1)=. Map (row key, column key, value) triples and separate the  and  results. mapEitherWithKeys (\r c a -> if r == 1 && c == 'a' then Left a else Right a) (fromList [(1,'a',"a"),(1,'b',"c"),(2,'b',"a")]) === (fromList [(1,'a',"a")],fromList [(1,'b',"c"),(2,'b',"a")])multi-containers.Build a table from a row map and a column map.CC9 9 Safe:X      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX    YZ !"%&'()*+,-./01234789:;<=>?@ABCDEF[\]^_`abcdefghijkl  mnopqrstuvwxy !z{|%&}~)*28=?-multi-containers-0.1.1-EeD5nrYn0VIIkbGZ0ardkm Data.MultimapData.Multimap.SetData.Multimap.TablePaths_multi_containersMultimapempty singletonfromListfromMapfromMap'insertdeletedeleteWithValue deleteOneadjust adjustWithKeyupdateupdate' updateWithKeyupdateWithKey'alter alterWithKeylookup!member notMembernullnotNullsizeunionunions differencemap mapWithKeytraverseWithKeytraverseMaybeWithKeyfoldrfoldl foldrWithKey foldlWithKeyfoldr'foldl' foldrWithKey' foldlWithKey'foldMapWithKeyelemskeyskeysSetassocstoList toAscList toDescList toAscListBF toDescListBFtoMapfilter filterKey filterWithKeyfilterMfilterWithKeyMmapMaybemapMaybeWithKey mapEithermapEitherWithKey lookupMin lookupMaxlookupLTlookupGTlookupLElookupGE$fMonoidMultimap$fSemigroupMultimap$fTraversableMultimap$fFoldableMultimap$fFunctorMultimap$fRead1Multimap$fReadMultimap$fShow2Multimap$fShow1Multimap$fShowMultimap$fOrd2Multimap$fOrd1Multimap $fEq2Multimap $fEq1Multimap $fEqMultimap $fOrdMultimap$fDataMultimap SetMultimap deleteMax deleteMin$fMonoidSetMultimap$fSemigroupSetMultimap$fFoldableSetMultimap$fReadSetMultimap$fShow2SetMultimap$fShow1SetMultimap$fShowSetMultimap$fOrd2SetMultimap$fOrd1SetMultimap$fEq2SetMultimap$fEq1SetMultimap$fEqSetMultimap$fOrdSetMultimap$fDataSetMultimapTable fromRowMap fromColumnMap transpose deleteRow deleteColumnadjustWithKeysupdateWithKeys alterWithKeys!?hasCellhasRow hasColumn unionWith unionWithKeys unionsWithunionsWithKeys mapWithKeystraverseWithKeystraverseMaybeWithKeys foldrWithKeys foldlWithKeysfoldrWithKeys'foldlWithKeys'foldMapWithKeysrowcolumnrowMap columnMaprowKeys columnKeys rowKeysSet columnKeysSet toRowAscListtoColumnAscList toRowDescListtoColumnDescList filterRow filterColumnfilterWithKeysmapMaybeWithKeysmapEitherWithKeys $fMonoidTable$fSemigroupTable$fTraversableTable$fFoldableTable$fFunctorTable $fReadTable $fShowTable $fEqTable $fOrdTable $fDataTablebase GHC.MaybeMaybeNothingGHC.BaseNonEmptyJust Data.EitherEitherLeftRightcontainers-0.6.0.1Data.Set.InternalSetGHC.ErrerrorfromMapsversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName