-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Assorted concrete container types
°5u
°5uThis package contains efficient general-purpose implementations of
°5uvarious immutable container types including sets, maps, sequences,
°5utrees, and graphs.
°5u
°5uFor a walkthrough of what this package provides with examples of
°5ucommon operations see the <a>containers introduction</a>.
°5u
°5uThe declared cost of each operation is either worst-case or amortized,
°5ubut remains valid even if structures are shared.
@package containers
@version 0.5.11.0


module Utils.Containers.Internal.BitUtil
bitcount :: Int -> Word -> Int

-- | Return a word where only the highest bit is set.
highestBitMask :: Word -> Word
shiftLL :: Word -> Int -> Word
shiftRL :: Word -> Int -> Word
wordSize :: Int


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uAn extremely light-weight, fast, and limited representation of a
°5ustring of up to (2*WORDSIZE - 2) bits. In fact, there are two
°5urepresentations, misleadingly named bit queue builder and bit queue.
°5uThe builder supports only <a>emptyQB</a>, creating an empty builder,
°5uand <a>snocQB</a>, enqueueing a bit. The bit queue builder is then
°5uturned into a bit queue using <a>buildQ</a>, after which bits can be
°5uremoved one by one using <a>unconsQ</a>. If the size limit is
°5uexceeded, further operations will silently produce nonsense.
module Utils.Containers.Internal.BitQueue
data BitQueue
data BitQueueB

-- | Create an empty bit queue builder. This is represented as a single
°5uguard bit in the most significant position.
emptyQB :: BitQueueB

-- | Enqueue a bit. This works by shifting the queue right one bit, then
°5usetting the most significant bit as requested.
snocQB :: BitQueueB -> Bool -> BitQueueB

-- | Convert a bit queue builder to a bit queue. This shifts in a new guard
°5ubit on the left, and shifts right until the old guard bit falls off.
buildQ :: BitQueueB -> BitQueue

-- | Dequeue an element, or discover the queue is empty.
unconsQ :: BitQueue -> Maybe (Bool, BitQueue)

-- | Convert a bit queue to a list of bits by unconsing. This is used to
°5utest that the queue functions properly.
toListQ :: BitQueue -> [Bool]
instance GHC.Show.Show Utils.Containers.Internal.BitQueue.BitQueue
instance GHC.Show.Show Utils.Containers.Internal.BitQueue.BitQueueB


-- | A strict pair
module Utils.Containers.Internal.StrictPair

-- | The same as a regular Haskell pair, but
°5u
°5u<pre>
°5u(x :*: _|_) = (_|_ :*: y) = _|_
°5u</pre>
data StrictPair a b
(:*:) :: !a -> !b -> StrictPair a b

-- | Convert a strict pair to a standard pair.
toPair :: StrictPair a b -> (a, b)


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uAn efficient implementation of sets.
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.Set (Set)
°5uimport qualified Data.Set as Set
°5u</pre>
°5u
°5uThe implementation of <a>Set</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
°5u
°5uNote that the implementation is <i>left-biased</i> -- the elements of
°5ua first argument are always preferred to the second, for example in
°5u<a>union</a> or <a>insert</a>. Of course, left-biasing can only be
°5uobserved when equality is an equivalence relation instead of
°5ustructural equality.
°5u
°5u<i>Warning</i>: The size of the set must not exceed
°5u<tt>maxBound::Int</tt>. Violation of this condition is not detected
°5uand if the size limit is exceeded, the behavior of the set is
°5ucompletely undefined.
module Data.Set.Internal

-- | A set of values <tt>a</tt>.
data Set a
Bin :: {-# UNPACK #-} !Size -> !a -> !(Set a) -> !(Set a) -> Set a
Tip :: Set a
type Size = Int

-- | <i>O(m*log(n/m+1)), m &lt;= n</i>. See <a>difference</a>.
(\\) :: Ord a => Set a -> Set a -> Set a
infixl 9 \\

-- | <i>O(1)</i>. Is this the empty set?
null :: Set a -> Bool

-- | <i>O(1)</i>. The number of elements in the set.
size :: Set a -> Int

-- | <i>O(log n)</i>. Is the element in the set?
member :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. Is the element not in the set?
notMember :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. Find largest element smaller than the given one.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [3, 5]) == Nothing
°5ulookupLT 5 (fromList [3, 5]) == Just 3
°5u</pre>
lookupLT :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find smallest element greater than the given one.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [3, 5]) == Just 5
°5ulookupGT 5 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGT :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find largest element smaller or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [3, 5]) == Nothing
°5ulookupLE 4 (fromList [3, 5]) == Just 3
°5ulookupLE 5 (fromList [3, 5]) == Just 5
°5u</pre>
lookupLE :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find smallest element greater or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [3, 5]) == Just 3
°5ulookupGE 4 (fromList [3, 5]) == Just 5
°5ulookupGE 6 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGE :: Ord a => a -> Set a -> Maybe a

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
°5utells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(n+m)</i>. Check whether two sets are disjoint (i.e. their
°5uintersection is empty).
°5u
°5u<pre>
°5udisjoint (fromList [2,4,6])   (fromList [1,3])     == True
°5udisjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
°5udisjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
°5udisjoint (fromList [])        (fromList [])        == True
°5u</pre>
disjoint :: Ord a => Set a -> Set a -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: Set a

-- | <i>O(1)</i>. Create a singleton set.
singleton :: a -> Set a

-- | <i>O(log n)</i>. Insert an element in a set. If the set already
°5ucontains an element equal to the given value, it is replaced with the
°5unew value.
insert :: Ord a => a -> Set a -> Set a

-- | <i>O(log n)</i>. Delete an element from a set.
delete :: Ord a => a -> Set a -> Set a

-- | Calculate the power set of a set: the set of all its subsets.
°5u
°5u<pre>
°5ut <a>member</a> powerSet s == t <a>isSubsetOf</a> s
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5upowerSet (fromList [1,2,3]) =
°5u  fromList [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]
°5u</pre>
powerSet :: Set a -> Set (Set a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The union of two sets, preferring
°5uthe first set when equal elements are encountered.
union :: Ord a => Set a -> Set a -> Set a

-- | The union of a list of sets: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
unions :: Ord a => [Set a] -> Set a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two sets.
difference :: Ord a => Set a -> Set a -> Set a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The intersection of two sets.
°5uElements of the result come from the first set, so for example
°5u
°5u<pre>
°5uimport qualified Data.Set as S
°5udata AB = A | B deriving Show
°5uinstance Ord AB where compare _ _ = EQ
°5uinstance Eq AB where _ == _ = True
°5umain = print (S.singleton A `S.intersection` S.singleton B,
°5u              S.singleton B `S.intersection` S.singleton A)
°5u</pre>
°5u
°5uprints <tt>(fromList [A],fromList [B])</tt>.
intersection :: Ord a => Set a -> Set a -> Set a

-- | Calculate the Cartesian product of two sets.
°5u
°5u<pre>
°5ucartesianProduct xs ys = fromList $ liftA2 (,) (toList xs) (toList ys)
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5ucartesianProduct (fromList [1,2]) (fromList [<tt>a</tt>,<tt>b</tt>]) =
°5u  fromList [(1,<tt>a</tt>), (1,<tt>b</tt>), (2,<tt>a</tt>), (2,<tt>b</tt>)]
°5u</pre>
cartesianProduct :: Set a -> Set b -> Set (a, b)

-- | Calculate the disjoin union of two sets.
°5u
°5u<pre>
°5udisjointUnion xs ys = map Left xs <a>union</a> map Right ys
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5udisjointUnion (fromList [1,2]) (fromList ["hi", "bye"]) =
°5u  fromList [Left 1, Left 2, Right "hi", Right "bye"]
°5u</pre>
disjointUnion :: Set a -> Set b -> Set (Either a b)

-- | <i>O(n)</i>. Filter all elements that satisfy the predicate.
filter :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Take while a predicate on the elements holds. The
°5uuser is responsible for ensuring that for all elements <tt>j</tt> and
°5u<tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
°5unote at <a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
°5utakeWhileAntitone p = <a>filter</a> p
°5u</pre>
takeWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Drop while a predicate on the elements holds. The
°5uuser is responsible for ensuring that for all elements <tt>j</tt> and
°5u<tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
°5unote at <a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
°5udropWhileAntitone p = <a>filter</a> (not . p)
°5u</pre>
dropWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Divide a set at the point where a predicate on the
°5uelements stops holding. The user is responsible for ensuring that for
°5uall elements <tt>j</tt> and <tt>k</tt> in the set, <tt>j &lt; k ==&gt;
°5up j &gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first element and to fail
°5uafter the last element).
spanAntitone :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | <i>O(n)</i>. Partition the set into two sets, one with all elements
°5uthat satisfy the predicate and one with all elements that don't
°5usatisfy the predicate. See also <a>split</a>.
partition :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> x set</tt>) is a
°5upair <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements
°5uof <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
°5uelements of <tt>set</tt> greater than <tt>x</tt>.
split :: Ord a => a -> Set a -> (Set a, Set a)

-- | <i>O(log n)</i>. Performs a <a>split</a> but also returns whether the
°5upivot element was found in the original set.
splitMember :: Ord a => a -> Set a -> (Set a, Bool, Set a)

-- | <i>O(1)</i>. Decompose a set into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a set in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst subset less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList [1..6]) ==
°5u  [fromList [1,2,3],fromList [4],fromList [5,6]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubsets, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Set a -> [Set a]

-- | <i>O(log n)</i>. Lookup the <i>index</i> of an element, which is its
°5uzero-based index in the sorted sequence of elements. The index is a
°5unumber from <i>0</i> up to, but not including, the <a>size</a> of the
°5uset.
°5u
°5u<pre>
°5uisJust   (lookupIndex 2 (fromList [5,3])) == False
°5ufromJust (lookupIndex 3 (fromList [5,3])) == 0
°5ufromJust (lookupIndex 5 (fromList [5,3])) == 1
°5uisJust   (lookupIndex 6 (fromList [5,3])) == False
°5u</pre>
lookupIndex :: Ord a => a -> Set a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of an element, which is its
°5uzero-based index in the sorted sequence of elements. The index is a
°5unumber from <i>0</i> up to, but not including, the <a>size</a> of the
°5uset. Calls <a>error</a> when the element is not a <a>member</a> of the
°5uset.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [5,3])    Error: element is not in the set
°5ufindIndex 3 (fromList [5,3]) == 0
°5ufindIndex 5 (fromList [5,3]) == 1
°5ufindIndex 6 (fromList [5,3])    Error: element is not in the set
°5u</pre>
findIndex :: Ord a => a -> Set a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sorted sequence of elements. If the
°5u<i>index</i> is out of range (less than zero, greater or equal to
°5u<a>size</a> of the set), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [5,3]) == 3
°5uelemAt 1 (fromList [5,3]) == 5
°5uelemAt 2 (fromList [5,3])    Error: index out of range
°5u</pre>
elemAt :: Int -> Set a -> a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sorted sequence of elements. If the
°5u<i>index</i> is out of range (less than zero, greater or equal to
°5u<a>size</a> of the set), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0    (fromList [5,3]) == singleton 5
°5udeleteAt 1    (fromList [5,3]) == singleton 3
°5udeleteAt 2    (fromList [5,3])    Error: index out of range
°5udeleteAt (-1) (fromList [5,3])    Error: index out of range
°5u</pre>
deleteAt :: Int -> Set a -> Set a

-- | Take a given number of elements in order, beginning with the smallest
°5uones.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Set a -> Set a

-- | Drop a given number of elements in order, beginning with the smallest
°5uones.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Set a -> Set a

-- | <i>O(log n)</i>. Split a set at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Set a -> (Set a, Set a)

-- | <i>O(n*log n)</i>. <tt><a>map</a> f s</tt> is the set obtained by
°5uapplying <tt>f</tt> to each element of <tt>s</tt>.
°5u
°5uIt's worth noting that the size of the result may be smaller if, for
°5usome <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: Ord b => (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. The
°5u
°5u<tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but works only
°5uwhen <tt>f</tt> is strictly increasing. <i>The precondition is not
°5uchecked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapMonotonic f s == map f s
°5u    where ls = toList s
°5u</pre>
mapMonotonic :: (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoAscList set = foldr (:) [] set
°5u</pre>
foldr :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoDescList set = foldl (flip (:)) [] set
°5u</pre>
foldl :: (a -> b -> a) -> a -> Set b -> a

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Set b -> a

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.
°5u
°5u<i>Please note that fold will be deprecated in the future and
°5uremoved.</i>
fold :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(log n)</i>. The minimal element of a set.
lookupMin :: Set a -> Maybe a

-- | <i>O(log n)</i>. The maximal element of a set.
lookupMax :: Set a -> Maybe a

-- | <i>O(log n)</i>. The minimal element of a set.
findMin :: Set a -> a

-- | <i>O(log n)</i>. The maximal element of a set.
findMax :: Set a -> a

-- | <i>O(log n)</i>. Delete the minimal element. Returns an empty set if
°5uthe set is empty.
deleteMin :: Set a -> Set a

-- | <i>O(log n)</i>. Delete the maximal element. Returns an empty set if
°5uthe set is empty.
deleteMax :: Set a -> Set a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin set = (findMin set, deleteMin set)
°5u</pre>
deleteFindMin :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax set = (findMax set, deleteMax set)
°5u</pre>
deleteFindMax :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. Retrieves the maximal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: Set a -> Maybe (a, Set a)

-- | <i>O(log n)</i>. Retrieves the minimal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: Set a -> Maybe (a, Set a)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
°5uascending order. Subject to list fusion.
elems :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
°5ufusion.
toList :: Set a -> [a]

-- | <i>O(n*log n)</i>. Create a set from a list of elements.
°5u
°5uIf the elements are ordered, a linear-time implementation is used,
°5uwith the performance equal to <a>fromDistinctAscList</a>.
fromList :: Ord a => [a] -> Set a

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
°5uto list fusion.
toAscList :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
°5uto list fusion.
toDescList :: Set a -> [a]

-- | <i>O(n)</i>. Build a set from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
fromAscList :: Eq a => [a] -> Set a

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements
°5uin linear time. <i>The precondition (input list is strictly ascending)
°5uis not checked.</i>
fromDistinctAscList :: [a] -> Set a

-- | <i>O(n)</i>. Build a set from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
fromDescList :: Eq a => [a] -> Set a

-- | <i>O(n)</i>. Build a set from a descending list of distinct elements
°5uin linear time. <i>The precondition (input list is strictly
°5udescending) is not checked.</i>
fromDistinctDescList :: [a] -> Set a

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
°5uin a compressed, hanging format.
showTree :: Show a => Set a -> String

-- | <i>O(n)</i>. The expression (<tt>showTreeWith hang wide map</tt>)
°5ushows the tree that implements the set. If <tt>hang</tt> is
°5u<tt>True</tt>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uSet&gt; putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]
°5u4
°5u+--2
°5u|  +--1
°5u|  +--3
°5u+--5
°5u
°5uSet&gt; putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]
°5u4
°5u|
°5u+--2
°5u|  |
°5u|  +--1
°5u|  |
°5u|  +--3
°5u|
°5u+--5
°5u
°5uSet&gt; putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]
°5u+--5
°5u|
°5u4
°5u|
°5u|  +--3
°5u|  |
°5u+--2
°5u   |
°5u   +--1
°5u</pre>
showTreeWith :: Show a => Bool -> Bool -> Set a -> String

-- | <i>O(n)</i>. Test if the internal set structure is valid.
valid :: Ord a => Set a -> Bool
bin :: a -> Set a -> Set a -> Set a
balanced :: Set a -> Bool
link :: a -> Set a -> Set a -> Set a
merge :: Set a -> Set a -> Set a
instance GHC.Base.Semigroup (Data.Set.Internal.MergeSet a)
instance GHC.Base.Monoid (Data.Set.Internal.MergeSet a)
instance GHC.Classes.Ord a => GHC.Base.Monoid (Data.Set.Internal.Set a)
instance GHC.Classes.Ord a => GHC.Base.Semigroup (Data.Set.Internal.Set a)
instance Data.Foldable.Foldable Data.Set.Internal.Set
instance (Data.Data.Data a, GHC.Classes.Ord a) => Data.Data.Data (Data.Set.Internal.Set a)
instance GHC.Classes.Ord a => GHC.Exts.IsList (Data.Set.Internal.Set a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Set.Internal.Set a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Set.Internal.Set a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Set.Internal.Set a)
instance Data.Functor.Classes.Eq1 Data.Set.Internal.Set
instance Data.Functor.Classes.Ord1 Data.Set.Internal.Set
instance Data.Functor.Classes.Show1 Data.Set.Internal.Set
instance (GHC.Read.Read a, GHC.Classes.Ord a) => GHC.Read.Read (Data.Set.Internal.Set a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Set.Internal.Set a)


-- | <h1>Finite Sets</h1>
°5u
°5uThe <tt><a>Set</a> e</tt> type represents a set of elements of type
°5u<tt>e</tt>. Most operations require that <tt>e</tt> be an instance of
°5uthe <a>Ord</a> class. A <a>Set</a> is strict in its elements.
°5u
°5uFor a walkthrough of the most commonly used functions see the <a>sets
°5uintroduction</a>.
°5u
°5uNote that the implementation is generally <i>left-biased</i>.
°5uFunctions that take two sets as arguments and combine them, such as
°5u<a>union</a> and <a>intersection</a>, prefer the entries in the first
°5uargument to those in the second. Of course, this bias can only be
°5uobserved when equality is an equivalence relation instead of
°5ustructural equality.
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.Set (Set)
°5uimport qualified Data.Set as Set
°5u</pre>
°5u
°5u<h2>Warning</h2>
°5u
°5uThe size of the set must not exceed <tt>maxBound::Int</tt>. Violation
°5uof this condition is not detected and if the size limit is exceeded,
°5uits behaviour is undefined.
°5u
°5u<h2>Implementation</h2>
°5u
°5uThe implementation of <a>Set</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
module Data.Set

-- | A set of values <tt>a</tt>.
data Set a

-- | <i>O(m*log(n/m+1)), m &lt;= n</i>. See <a>difference</a>.
(\\) :: Ord a => Set a -> Set a -> Set a
infixl 9 \\

-- | <i>O(1)</i>. Is this the empty set?
null :: Set a -> Bool

-- | <i>O(1)</i>. The number of elements in the set.
size :: Set a -> Int

-- | <i>O(log n)</i>. Is the element in the set?
member :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. Is the element not in the set?
notMember :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. Find largest element smaller than the given one.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [3, 5]) == Nothing
°5ulookupLT 5 (fromList [3, 5]) == Just 3
°5u</pre>
lookupLT :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find smallest element greater than the given one.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [3, 5]) == Just 5
°5ulookupGT 5 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGT :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find largest element smaller or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [3, 5]) == Nothing
°5ulookupLE 4 (fromList [3, 5]) == Just 3
°5ulookupLE 5 (fromList [3, 5]) == Just 5
°5u</pre>
lookupLE :: Ord a => a -> Set a -> Maybe a

-- | <i>O(log n)</i>. Find smallest element greater or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [3, 5]) == Just 3
°5ulookupGE 4 (fromList [3, 5]) == Just 5
°5ulookupGE 6 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGE :: Ord a => a -> Set a -> Maybe a

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
°5utells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(n+m)</i>. Check whether two sets are disjoint (i.e. their
°5uintersection is empty).
°5u
°5u<pre>
°5udisjoint (fromList [2,4,6])   (fromList [1,3])     == True
°5udisjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
°5udisjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
°5udisjoint (fromList [])        (fromList [])        == True
°5u</pre>
disjoint :: Ord a => Set a -> Set a -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: Set a

-- | <i>O(1)</i>. Create a singleton set.
singleton :: a -> Set a

-- | <i>O(log n)</i>. Insert an element in a set. If the set already
°5ucontains an element equal to the given value, it is replaced with the
°5unew value.
insert :: Ord a => a -> Set a -> Set a

-- | <i>O(log n)</i>. Delete an element from a set.
delete :: Ord a => a -> Set a -> Set a

-- | Calculate the power set of a set: the set of all its subsets.
°5u
°5u<pre>
°5ut <a>member</a> powerSet s == t <a>isSubsetOf</a> s
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5upowerSet (fromList [1,2,3]) =
°5u  fromList [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]
°5u</pre>
powerSet :: Set a -> Set (Set a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The union of two sets, preferring
°5uthe first set when equal elements are encountered.
union :: Ord a => Set a -> Set a -> Set a

-- | The union of a list of sets: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
unions :: Ord a => [Set a] -> Set a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two sets.
difference :: Ord a => Set a -> Set a -> Set a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The intersection of two sets.
°5uElements of the result come from the first set, so for example
°5u
°5u<pre>
°5uimport qualified Data.Set as S
°5udata AB = A | B deriving Show
°5uinstance Ord AB where compare _ _ = EQ
°5uinstance Eq AB where _ == _ = True
°5umain = print (S.singleton A `S.intersection` S.singleton B,
°5u              S.singleton B `S.intersection` S.singleton A)
°5u</pre>
°5u
°5uprints <tt>(fromList [A],fromList [B])</tt>.
intersection :: Ord a => Set a -> Set a -> Set a

-- | Calculate the Cartesian product of two sets.
°5u
°5u<pre>
°5ucartesianProduct xs ys = fromList $ liftA2 (,) (toList xs) (toList ys)
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5ucartesianProduct (fromList [1,2]) (fromList [<tt>a</tt>,<tt>b</tt>]) =
°5u  fromList [(1,<tt>a</tt>), (1,<tt>b</tt>), (2,<tt>a</tt>), (2,<tt>b</tt>)]
°5u</pre>
cartesianProduct :: Set a -> Set b -> Set (a, b)

-- | Calculate the disjoin union of two sets.
°5u
°5u<pre>
°5udisjointUnion xs ys = map Left xs <a>union</a> map Right ys
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5udisjointUnion (fromList [1,2]) (fromList ["hi", "bye"]) =
°5u  fromList [Left 1, Left 2, Right "hi", Right "bye"]
°5u</pre>
disjointUnion :: Set a -> Set b -> Set (Either a b)

-- | <i>O(n)</i>. Filter all elements that satisfy the predicate.
filter :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Take while a predicate on the elements holds. The
°5uuser is responsible for ensuring that for all elements <tt>j</tt> and
°5u<tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
°5unote at <a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
°5utakeWhileAntitone p = <a>filter</a> p
°5u</pre>
takeWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Drop while a predicate on the elements holds. The
°5uuser is responsible for ensuring that for all elements <tt>j</tt> and
°5u<tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
°5unote at <a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
°5udropWhileAntitone p = <a>filter</a> (not . p)
°5u</pre>
dropWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | <i>O(log n)</i>. Divide a set at the point where a predicate on the
°5uelements stops holding. The user is responsible for ensuring that for
°5uall elements <tt>j</tt> and <tt>k</tt> in the set, <tt>j &lt; k ==&gt;
°5up j &gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first element and to fail
°5uafter the last element).
spanAntitone :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | <i>O(n)</i>. Partition the set into two sets, one with all elements
°5uthat satisfy the predicate and one with all elements that don't
°5usatisfy the predicate. See also <a>split</a>.
partition :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> x set</tt>) is a
°5upair <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements
°5uof <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
°5uelements of <tt>set</tt> greater than <tt>x</tt>.
split :: Ord a => a -> Set a -> (Set a, Set a)

-- | <i>O(log n)</i>. Performs a <a>split</a> but also returns whether the
°5upivot element was found in the original set.
splitMember :: Ord a => a -> Set a -> (Set a, Bool, Set a)

-- | <i>O(1)</i>. Decompose a set into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a set in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst subset less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList [1..6]) ==
°5u  [fromList [1,2,3],fromList [4],fromList [5,6]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubsets, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Set a -> [Set a]

-- | <i>O(log n)</i>. Lookup the <i>index</i> of an element, which is its
°5uzero-based index in the sorted sequence of elements. The index is a
°5unumber from <i>0</i> up to, but not including, the <a>size</a> of the
°5uset.
°5u
°5u<pre>
°5uisJust   (lookupIndex 2 (fromList [5,3])) == False
°5ufromJust (lookupIndex 3 (fromList [5,3])) == 0
°5ufromJust (lookupIndex 5 (fromList [5,3])) == 1
°5uisJust   (lookupIndex 6 (fromList [5,3])) == False
°5u</pre>
lookupIndex :: Ord a => a -> Set a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of an element, which is its
°5uzero-based index in the sorted sequence of elements. The index is a
°5unumber from <i>0</i> up to, but not including, the <a>size</a> of the
°5uset. Calls <a>error</a> when the element is not a <a>member</a> of the
°5uset.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [5,3])    Error: element is not in the set
°5ufindIndex 3 (fromList [5,3]) == 0
°5ufindIndex 5 (fromList [5,3]) == 1
°5ufindIndex 6 (fromList [5,3])    Error: element is not in the set
°5u</pre>
findIndex :: Ord a => a -> Set a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sorted sequence of elements. If the
°5u<i>index</i> is out of range (less than zero, greater or equal to
°5u<a>size</a> of the set), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [5,3]) == 3
°5uelemAt 1 (fromList [5,3]) == 5
°5uelemAt 2 (fromList [5,3])    Error: index out of range
°5u</pre>
elemAt :: Int -> Set a -> a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sorted sequence of elements. If the
°5u<i>index</i> is out of range (less than zero, greater or equal to
°5u<a>size</a> of the set), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0    (fromList [5,3]) == singleton 5
°5udeleteAt 1    (fromList [5,3]) == singleton 3
°5udeleteAt 2    (fromList [5,3])    Error: index out of range
°5udeleteAt (-1) (fromList [5,3])    Error: index out of range
°5u</pre>
deleteAt :: Int -> Set a -> Set a

-- | Take a given number of elements in order, beginning with the smallest
°5uones.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Set a -> Set a

-- | Drop a given number of elements in order, beginning with the smallest
°5uones.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Set a -> Set a

-- | <i>O(log n)</i>. Split a set at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Set a -> (Set a, Set a)

-- | <i>O(n*log n)</i>. <tt><a>map</a> f s</tt> is the set obtained by
°5uapplying <tt>f</tt> to each element of <tt>s</tt>.
°5u
°5uIt's worth noting that the size of the result may be smaller if, for
°5usome <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: Ord b => (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. The
°5u
°5u<tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but works only
°5uwhen <tt>f</tt> is strictly increasing. <i>The precondition is not
°5uchecked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapMonotonic f s == map f s
°5u    where ls = toList s
°5u</pre>
mapMonotonic :: (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoAscList set = foldr (:) [] set
°5u</pre>
foldr :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoDescList set = foldl (flip (:)) [] set
°5u</pre>
foldl :: (a -> b -> a) -> a -> Set b -> a

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Set b -> a

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.
°5u
°5u<i>Please note that fold will be deprecated in the future and
°5uremoved.</i>
fold :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(log n)</i>. The minimal element of a set.
lookupMin :: Set a -> Maybe a

-- | <i>O(log n)</i>. The maximal element of a set.
lookupMax :: Set a -> Maybe a

-- | <i>O(log n)</i>. The minimal element of a set.
findMin :: Set a -> a

-- | <i>O(log n)</i>. The maximal element of a set.
findMax :: Set a -> a

-- | <i>O(log n)</i>. Delete the minimal element. Returns an empty set if
°5uthe set is empty.
deleteMin :: Set a -> Set a

-- | <i>O(log n)</i>. Delete the maximal element. Returns an empty set if
°5uthe set is empty.
deleteMax :: Set a -> Set a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin set = (findMin set, deleteMin set)
°5u</pre>
deleteFindMin :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax set = (findMax set, deleteMax set)
°5u</pre>
deleteFindMax :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. Retrieves the maximal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: Set a -> Maybe (a, Set a)

-- | <i>O(log n)</i>. Retrieves the minimal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: Set a -> Maybe (a, Set a)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
°5uascending order. Subject to list fusion.
elems :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
°5ufusion.
toList :: Set a -> [a]

-- | <i>O(n*log n)</i>. Create a set from a list of elements.
°5u
°5uIf the elements are ordered, a linear-time implementation is used,
°5uwith the performance equal to <a>fromDistinctAscList</a>.
fromList :: Ord a => [a] -> Set a

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
°5uto list fusion.
toAscList :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
°5uto list fusion.
toDescList :: Set a -> [a]

-- | <i>O(n)</i>. Build a set from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
fromAscList :: Eq a => [a] -> Set a

-- | <i>O(n)</i>. Build a set from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
fromDescList :: Eq a => [a] -> Set a

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements
°5uin linear time. <i>The precondition (input list is strictly ascending)
°5uis not checked.</i>
fromDistinctAscList :: [a] -> Set a

-- | <i>O(n)</i>. Build a set from a descending list of distinct elements
°5uin linear time. <i>The precondition (input list is strictly
°5udescending) is not checked.</i>
fromDistinctDescList :: [a] -> Set a

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
°5uin a compressed, hanging format.
showTree :: Show a => Set a -> String

-- | <i>O(n)</i>. The expression (<tt>showTreeWith hang wide map</tt>)
°5ushows the tree that implements the set. If <tt>hang</tt> is
°5u<tt>True</tt>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uSet&gt; putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]
°5u4
°5u+--2
°5u|  +--1
°5u|  +--3
°5u+--5
°5u
°5uSet&gt; putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]
°5u4
°5u|
°5u+--2
°5u|  |
°5u|  +--1
°5u|  |
°5u|  +--3
°5u|
°5u+--5
°5u
°5uSet&gt; putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]
°5u+--5
°5u|
°5u4
°5u|
°5u|  +--3
°5u|  |
°5u+--2
°5u   |
°5u   +--1
°5u</pre>
showTreeWith :: Show a => Bool -> Bool -> Set a -> String

-- | <i>O(n)</i>. Test if the internal set structure is valid.
valid :: Ord a => Set a -> Bool


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uGeneral purpose finite sequences. Apart from being finite and having
°5ustrict operations, sequences also differ from lists in supporting a
°5uwider variety of operations efficiently.
°5u
°5uAn amortized running time is given for each operation, with
°5u&lt;math&gt; referring to the length of the sequence and &lt;math&gt;
°5ubeing the integral index used by some operations. These bounds hold
°5ueven in a persistent (shared) setting.
°5u
°5uThe implementation uses 2-3 finger trees annotated with sizes, as
°5udescribed in section 4.2 of
°5u
°5u<ul>
°5u<li>Ralf Hinze and Ross Paterson, "Finger trees: a simple
°5ugeneral-purpose data structure", <i>Journal of Functional
°5uProgramming</i> 16:2 (2006) pp 197-217.
°5u<a>http://staff.city.ac.uk/~ross/papers/FingerTree.html</a></li>
°5u</ul>
°5u
°5u<i>Note</i>: Many of these operations have the same names as similar
°5uoperations on lists in the <a>Prelude</a>. The ambiguity may be
°5uresolved using either qualification or the <tt>hiding</tt> clause.
°5u
°5u<i>Warning</i>: The size of a <a>Seq</a> must not exceed
°5u<tt>maxBound::Int</tt>. Violation of this condition is not detected
°5uand if the size limit is exceeded, the behaviour of the sequence is
°5uundefined. This is unlikely to occur in most applications, but some
°5ucare may be required when using <a>&gt;&lt;</a>, <a>&lt;*&gt;</a>,
°5u<a>*&gt;</a>, or <a>&gt;&gt;</a>, particularly repeatedly and
°5uparticularly in combination with <a>replicate</a> or
°5u<a>fromFunction</a>.
module Data.Sequence.Internal
newtype Elem a
Elem :: a -> Elem a
[getElem] :: Elem a -> a
data FingerTree a
EmptyT :: FingerTree a
Single :: a -> FingerTree a
Deep :: {-# UNPACK #-} !Int -> !(Digit a) -> (FingerTree (Node a)) -> !(Digit a) -> FingerTree a
data Node a
Node2 :: {-# UNPACK #-} !Int -> a -> a -> Node a
Node3 :: {-# UNPACK #-} !Int -> a -> a -> a -> Node a
data Digit a
One :: a -> Digit a
Two :: a -> a -> Digit a
Three :: a -> a -> a -> Digit a
Four :: a -> a -> a -> a -> Digit a
class Sized a
size :: Sized a => a -> Int
class MaybeForce a

-- | General-purpose finite sequences.
newtype Seq a
Seq :: (FingerTree (Elem a)) -> Seq a
newtype State s a
State :: s -> (s, a) -> State s a
[runState] :: State s a -> s -> (s, a)
execState :: State s a -> s -> a
foldDigit :: (b -> b -> b) -> (a -> b) -> Digit a -> b
foldNode :: (b -> b -> b) -> (a -> b) -> Node a -> b
foldWithIndexDigit :: Sized a => (b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
foldWithIndexNode :: Sized a => (m -> m -> m) -> (Int -> a -> m) -> Int -> Node a -> m

-- | &lt;math&gt;. The empty sequence.
empty :: Seq a

-- | &lt;math&gt;. A singleton sequence.
singleton :: a -> Seq a

-- | &lt;math&gt;. Add an element to the left end of a sequence. Mnemonic:
°5ua triangle with the single element at the pointy end.
(<|) :: a -> Seq a -> Seq a
infixr 5 <|

-- | &lt;math&gt;. Add an element to the right end of a sequence. Mnemonic:
°5ua triangle with the single element at the pointy end.
(|>) :: Seq a -> a -> Seq a
infixl 5 |>

-- | &lt;math&gt;. Concatenate two sequences.
(><) :: Seq a -> Seq a -> Seq a
infixr 5 ><

-- | &lt;math&gt;. Create a sequence from a finite list of elements. There
°5uis a function <a>toList</a> in the opposite direction for all
°5uinstances of the <a>Foldable</a> class, including <a>Seq</a>.
fromList :: [a] -> Seq a

-- | &lt;math&gt;. Convert a given sequence length and a function
°5urepresenting that sequence into a sequence.
fromFunction :: Int -> (Int -> a) -> Seq a

-- | &lt;math&gt;. Create a sequence consisting of the elements of an
°5u<a>Array</a>. Note that the resulting sequence elements may be
°5uevaluated lazily (as on GHC), so you must force the entire structure
°5uto be sure that the original array can be garbage-collected.
fromArray :: Ix i => Array i a -> Seq a

-- | &lt;math&gt;. <tt>replicate n x</tt> is a sequence consisting of
°5u<tt>n</tt> copies of <tt>x</tt>.
replicate :: Int -> a -> Seq a

-- | <a>replicateA</a> is an <a>Applicative</a> version of
°5u<a>replicate</a>, and makes &lt;math&gt; calls to <a>liftA2</a> and
°5u<a>pure</a>.
°5u
°5u<pre>
°5ureplicateA n x = sequenceA (replicate n x)
°5u</pre>
replicateA :: Applicative f => Int -> f a -> f (Seq a)

-- | <a>replicateM</a> is a sequence counterpart of <a>replicateM</a>.
°5u
°5u<pre>
°5ureplicateM n x = sequence (replicate n x)
°5u</pre>
°5u
°5uFor <tt>base &gt;= 4.8.0</tt> and <tt>containers &gt;= 0.5.11</tt>,
°5u<a>replicateM</a> is a synonym for <a>replicateA</a>.
replicateM :: Applicative m => Int -> m a -> m (Seq a)

-- | <i>O(</i>log<i> k)</i>. <tt><a>cycleTaking</a> k xs</tt> forms a
°5usequence of length <tt>k</tt> by repeatedly concatenating <tt>xs</tt>
°5uwith itself. <tt>xs</tt> may only be empty if <tt>k</tt> is 0.
°5u
°5u<pre>
°5ucycleTaking k = fromList . take k . cycle . toList
°5u</pre>
cycleTaking :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Constructs a sequence by repeated application of a
°5ufunction to a seed value.
°5u
°5u<pre>
°5uiterateN n f x = fromList (Prelude.take n (Prelude.iterate f x))
°5u</pre>
iterateN :: Int -> (a -> a) -> a -> Seq a

-- | Builds a sequence from a seed value. Takes time linear in the number
°5uof generated elements. <i>WARNING:</i> If the number of generated
°5uelements is infinite, this method will not terminate.
unfoldr :: (b -> Maybe (a, b)) -> b -> Seq a

-- | <tt><a>unfoldl</a> f x</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>unfoldr</a> (<a>fmap</a> swap . f) x)</tt>.
unfoldl :: (b -> Maybe (b, a)) -> b -> Seq a

-- | &lt;math&gt;. Is this the empty sequence?
null :: Seq a -> Bool

-- | &lt;math&gt;. The number of elements in the sequence.
length :: Seq a -> Int

-- | View of the left end of a sequence.
data ViewL a

-- | empty sequence
EmptyL :: ViewL a

-- | leftmost element and the rest of the sequence
(:<) :: a -> Seq a -> ViewL a

-- | &lt;math&gt;. Analyse the left end of a sequence.
viewl :: Seq a -> ViewL a

-- | View of the right end of a sequence.
data ViewR a

-- | empty sequence
EmptyR :: ViewR a

-- | the sequence minus the rightmost element, and the rightmost element
(:>) :: Seq a -> a -> ViewR a

-- | &lt;math&gt;. Analyse the right end of a sequence.
viewr :: Seq a -> ViewR a

-- | <a>scanl</a> is similar to <a>foldl</a>, but returns a sequence of
°5ureduced values from the left:
°5u
°5u<pre>
°5uscanl f z (fromList [x1, x2, ...]) = fromList [z, z `f` x1, (z `f` x1) `f` x2, ...]
°5u</pre>
scanl :: (a -> b -> a) -> a -> Seq b -> Seq a

-- | <a>scanl1</a> is a variant of <a>scanl</a> that has no starting value
°5uargument:
°5u
°5u<pre>
°5uscanl1 f (fromList [x1, x2, ...]) = fromList [x1, x1 `f` x2, ...]
°5u</pre>
scanl1 :: (a -> a -> a) -> Seq a -> Seq a

-- | <a>scanr</a> is the right-to-left dual of <a>scanl</a>.
scanr :: (a -> b -> b) -> b -> Seq a -> Seq b

-- | <a>scanr1</a> is a variant of <a>scanr</a> that has no starting value
°5uargument.
scanr1 :: (a -> a -> a) -> Seq a -> Seq a

-- | &lt;math&gt;. Returns a sequence of all suffixes of this sequence,
°5ulongest first. For example,
°5u
°5u<pre>
°5utails (fromList "abc") = fromList [fromList "abc", fromList "bc", fromList "c", fromList ""]
°5u</pre>
°5u
°5uEvaluating the &lt;math&gt;th suffix takes &lt;math&gt;, but
°5uevaluating every suffix in the sequence takes &lt;math&gt; due to
°5usharing.
tails :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. Returns a sequence of all prefixes of this sequence,
°5ushortest first. For example,
°5u
°5u<pre>
°5uinits (fromList "abc") = fromList [fromList "", fromList "a", fromList "ab", fromList "abc"]
°5u</pre>
°5u
°5uEvaluating the &lt;math&gt;th prefix takes &lt;math&gt;, but
°5uevaluating every prefix in the sequence takes &lt;math&gt; due to
°5usharing.
inits :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. <tt>chunksOf c xs</tt> splits <tt>xs</tt> into chunks of
°5usize <tt>c&gt;0</tt>. If <tt>c</tt> does not divide the length of
°5u<tt>xs</tt> evenly, then the last element of the result will be short.
°5u
°5uSide note: the given performance bound is missing some messy terms
°5uthat only really affect edge cases. Performance degrades smoothly from
°5u&lt;math&gt; (for &lt;math&gt;) to &lt;math&gt; (for &lt;math&gt;).
°5uThe true bound is more like &lt;math&gt;
chunksOf :: Int -> Seq a -> Seq (Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
°5u<a>takeWhileL</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns the longest prefix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt>.
takeWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
°5u<a>takeWhileR</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns the longest suffix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt>.
°5u
°5u<tt><a>takeWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>takeWhileL</a> p (<a>reverse</a> xs))</tt>.
takeWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
°5u<tt><a>dropWhileL</a> p xs</tt> returns the suffix remaining after
°5u<tt><a>takeWhileL</a> p xs</tt>.
dropWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
°5u<tt><a>dropWhileR</a> p xs</tt> returns the prefix remaining after
°5u<tt><a>takeWhileR</a> p xs</tt>.
°5u
°5u<tt><a>dropWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>dropWhileL</a> p (<a>reverse</a> xs))</tt>.
dropWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length. <a>spanl</a>,
°5uapplied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
°5ua pair whose first element is the longest prefix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt> and the second element
°5uis the remainder of the sequence.
spanl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the suffix length. <a>spanr</a>,
°5uapplied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
°5ua pair whose <i>first</i> element is the longest <i>suffix</i>
°5u(possibly empty) of <tt>xs</tt> of elements that satisfy <tt>p</tt>
°5uand the second element is the remainder of the sequence.
spanr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the breakpoint index.
°5u<a>breakl</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns a pair whose first element is the longest prefix
°5u(possibly empty) of <tt>xs</tt> of elements that <i>do not satisfy</i>
°5u<tt>p</tt> and the second element is the remainder of the sequence.
°5u
°5u<tt><a>breakl</a> p</tt> is equivalent to <tt><a>spanl</a> (not .
°5up)</tt>.
breakl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | <tt><a>breakr</a> p</tt> is equivalent to <tt><a>spanr</a> (not .
°5up)</tt>.
breakr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>partition</a> function takes a predicate
°5u<tt>p</tt> and a sequence <tt>xs</tt> and returns sequences of those
°5uelements which do and do not satisfy the predicate.
partition :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>filter</a> function takes a predicate <tt>p</tt>
°5uand a sequence <tt>xs</tt> and returns a sequence of those elements
°5uwhich satisfy the predicate.
filter :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
°5uIf the specified position is negative or at least the length of the
°5usequence, <a>lookup</a> returns <a>Nothing</a>.
°5u
°5u<pre>
°5u0 &lt;= i &lt; length xs ==&gt; lookup i xs == Just (toList xs !! i)
°5u</pre>
°5u
°5u<pre>
°5ui &lt; 0 || i &gt;= length xs ==&gt; lookup i xs = Nothing
°5u</pre>
°5u
°5uUnlike <a>index</a>, this can be used to retrieve an element without
°5uforcing it. For example, to insert the fifth element of a sequence
°5u<tt>xs</tt> into a <a>Map</a> <tt>m</tt> at key <tt>k</tt>, you could
°5uuse
°5u
°5u<pre>
°5ucase lookup 5 xs of
°5u  Nothing -&gt; m
°5u  Just x -&gt; <a>insert</a> k x m
°5u</pre>
lookup :: Int -> Seq a -> Maybe a

-- | &lt;math&gt;. A flipped, infix version of <a>lookup</a>.
(!?) :: Seq a -> Int -> Maybe a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
°5uThe argument should thus be a non-negative integer less than the size
°5uof the sequence. If the position is out of range, <a>index</a> fails
°5uwith an error.
°5u
°5u<pre>
°5uxs `index` i = toList xs !! i
°5u</pre>
°5u
°5uCaution: <a>index</a> necessarily delays retrieving the requested
°5uelement until the result is forced. It can therefore lead to a space
°5uleak if the result is stored, unforced, in another structure. To
°5uretrieve an element immediately without forcing it, use <a>lookup</a>
°5uor '(!?)'.
index :: Seq a -> Int -> a

-- | &lt;math&gt;. Update the element at the specified position. If the
°5uposition is out of range, the original sequence is returned.
°5u<a>adjust</a> can lead to poor performance and even memory leaks,
°5ubecause it does not force the new value before installing it in the
°5usequence. <a>adjust'</a> should usually be preferred.
adjust :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Update the element at the specified position. If the
°5uposition is out of range, the original sequence is returned. The new
°5uvalue is forced before it is installed in the sequence.
°5u
°5u<pre>
°5uadjust' f i xs =
°5u case xs !? i of
°5u   Nothing -&gt; xs
°5u   Just x -&gt; let !x' = f x
°5u             in update i x' xs
°5u</pre>
adjust' :: forall a. (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Replace the element at the specified position. If the
°5uposition is out of range, the original sequence is returned.
update :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. The first <tt>i</tt> elements of a sequence. If
°5u<tt>i</tt> is negative, <tt><a>take</a> i s</tt> yields the empty
°5usequence. If the sequence contains fewer than <tt>i</tt> elements, the
°5uwhole sequence is returned.
take :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Elements of a sequence after the first <tt>i</tt>. If
°5u<tt>i</tt> is negative, <tt><a>drop</a> i s</tt> yields the whole
°5usequence. If the sequence contains fewer than <tt>i</tt> elements, the
°5uempty sequence is returned.
drop :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. <tt><a>insertAt</a> i x xs</tt> inserts <tt>x</tt> into
°5u<tt>xs</tt> at the index <tt>i</tt>, shifting the rest of the sequence
°5uover.
°5u
°5u<pre>
°5uinsertAt 2 x (fromList [a,b,c,d]) = fromList [a,b,x,c,d]
°5uinsertAt 4 x (fromList [a,b,c,d]) = insertAt 10 x (fromList [a,b,c,d])
°5u                                  = fromList [a,b,c,d,x]
°5u</pre>
°5u
°5u<pre>
°5uinsertAt i x xs = take i xs &gt;&lt; singleton x &gt;&lt; drop i xs
°5u</pre>
insertAt :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. Delete the element of a sequence at a given index.
°5uReturn the original sequence if the index is out of range.
°5u
°5u<pre>
°5udeleteAt 2 [a,b,c,d] = [a,b,d]
°5udeleteAt 4 [a,b,c,d] = deleteAt (-1) [a,b,c,d] = [a,b,c,d]
°5u</pre>
deleteAt :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Split a sequence at a given position. <tt><a>splitAt</a>
°5ui s = (<a>take</a> i s, <a>drop</a> i s)</tt>.
splitAt :: Int -> Seq a -> (Seq a, Seq a)

-- | <a>elemIndexL</a> finds the leftmost index of the specified element,
°5uif it is present, and otherwise <a>Nothing</a>.
elemIndexL :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesL</a> finds the indices of the specified element, from
°5uleft to right (i.e. in ascending order).
elemIndicesL :: Eq a => a -> Seq a -> [Int]

-- | <a>elemIndexR</a> finds the rightmost index of the specified element,
°5uif it is present, and otherwise <a>Nothing</a>.
elemIndexR :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesR</a> finds the indices of the specified element, from
°5uright to left (i.e. in descending order).
elemIndicesR :: Eq a => a -> Seq a -> [Int]

-- | <tt><a>findIndexL</a> p xs</tt> finds the index of the leftmost
°5uelement that satisfies <tt>p</tt>, if any exist.
findIndexL :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesL</a> p</tt> finds all indices of elements that
°5usatisfy <tt>p</tt>, in ascending order.
findIndicesL :: (a -> Bool) -> Seq a -> [Int]

-- | <tt><a>findIndexR</a> p xs</tt> finds the index of the rightmost
°5uelement that satisfies <tt>p</tt>, if any exist.
findIndexR :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesR</a> p</tt> finds all indices of elements that
°5usatisfy <tt>p</tt>, in descending order.
findIndicesR :: (a -> Bool) -> Seq a -> [Int]
foldMapWithIndex :: Monoid m => (Int -> a -> m) -> Seq a -> m

-- | <a>foldlWithIndex</a> is a version of <a>foldl</a> that also provides
°5uaccess to the index of each element.
foldlWithIndex :: (b -> Int -> a -> b) -> b -> Seq a -> b

-- | <a>foldrWithIndex</a> is a version of <a>foldr</a> that also provides
°5uaccess to the index of each element.
foldrWithIndex :: (Int -> a -> b -> b) -> b -> Seq a -> b

-- | A generalization of <a>fmap</a>, <a>mapWithIndex</a> takes a mapping
°5ufunction that also depends on the element's index, and applies it to
°5uevery element in the sequence.
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b

-- | <a>traverseWithIndex</a> is a version of <a>traverse</a> that also
°5uoffers access to the index of each element.
traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)

-- | &lt;math&gt;. The reverse of a sequence.
reverse :: Seq a -> Seq a

-- | &lt;math&gt;. Intersperse an element between the elements of a
°5usequence.
°5u
°5u<pre>
°5uintersperse a empty = empty
°5uintersperse a (singleton x) = singleton x
°5uintersperse a (fromList [x,y]) = fromList [x,a,y]
°5uintersperse a (fromList [x,y,z]) = fromList [x,a,y,a,z]
°5u</pre>
intersperse :: a -> Seq a -> Seq a
liftA2Seq :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip</a> takes two sequences and returns a sequence of
°5ucorresponding pairs. If one input is short, excess elements are
°5udiscarded from the right end of the longer sequence.
zip :: Seq a -> Seq b -> Seq (a, b)

-- | &lt;math&gt;. <a>zipWith</a> generalizes <a>zip</a> by zipping with
°5uthe function given as the first argument, instead of a tupling
°5ufunction. For example, <tt>zipWith (+)</tt> is applied to two
°5usequences to take the sequence of corresponding sums.
zipWith :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip3</a> takes three sequences and returns a sequence
°5uof triples, analogous to <a>zip</a>.
zip3 :: Seq a -> Seq b -> Seq c -> Seq (a, b, c)

-- | &lt;math&gt;. <a>zipWith3</a> takes a function which combines three
°5uelements, as well as three sequences and returns a sequence of their
°5upoint-wise combinations, analogous to <a>zipWith</a>.
zipWith3 :: (a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d

-- | &lt;math&gt;. <a>zip4</a> takes four sequences and returns a sequence
°5uof quadruples, analogous to <a>zip</a>.
zip4 :: Seq a -> Seq b -> Seq c -> Seq d -> Seq (a, b, c, d)

-- | &lt;math&gt;. <a>zipWith4</a> takes a function which combines four
°5uelements, as well as four sequences and returns a sequence of their
°5upoint-wise combinations, analogous to <a>zipWith</a>.
zipWith4 :: (a -> b -> c -> d -> e) -> Seq a -> Seq b -> Seq c -> Seq d -> Seq e

-- | Unzip a sequence of pairs.
°5u
°5u<pre>
°5uunzip ps = ps `<tt>seq'</tt> (<a>fmap</a> <a>fst</a> ps) (<a>fmap</a> <a>snd</a> ps)
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5uunzip $ fromList [(1,"a"), (2,"b"), (3,"c")] =
°5u  (fromList [1,2,3], fromList ["a", "b", "c"])
°5u</pre>
°5u
°5uSee the note about efficiency at <a>unzipWith</a>.
unzip :: Seq (a, b) -> (Seq a, Seq b)

-- | &lt;math&gt;. Unzip a sequence using a function to divide elements.
°5u
°5u<pre>
°5uunzipWith f xs == <a>unzip</a> (<a>fmap</a> f xs)
°5u</pre>
°5u
°5uEfficiency note:
°5u
°5u<tt>unzipWith</tt> produces its two results in lockstep. If you
°5ucalculate <tt> unzipWith f xs </tt> and fully force <i>either</i> of
°5uthe results, then the entire structure of the <i>other</i> one will be
°5ubuilt as well. This behavior allows the garbage collector to collect
°5ueach calculated pair component as soon as it dies, without having to
°5uwait for its mate to die. If you do not need this behavior, you may be
°5ubetter off simply calculating the sequence of pairs and using
°5u<a>fmap</a> to extract each component sequence.
unzipWith :: (a -> (b, c)) -> Seq a -> (Seq b, Seq c)
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.Internal.ViewR a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.Internal.ViewR a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.Internal.ViewR a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.Internal.ViewR a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.Internal.ViewL a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.Internal.ViewL a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.Internal.ViewL a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.Internal.ViewL a)
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.Internal.ViewL a)
instance GHC.Generics.Generic1 Data.Sequence.Internal.ViewL
instance GHC.Generics.Generic (Data.Sequence.Internal.ViewL a)
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.Internal.ViewR a)
instance GHC.Generics.Generic1 Data.Sequence.Internal.ViewR
instance GHC.Generics.Generic (Data.Sequence.Internal.ViewR a)
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Elem
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Node
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Digit
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.FingerTree
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Seq
instance GHC.Base.Functor Data.Sequence.Internal.ViewR
instance Data.Foldable.Foldable Data.Sequence.Internal.ViewR
instance Data.Traversable.Traversable Data.Sequence.Internal.ViewR
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.Internal.Seq a)
instance GHC.Base.Functor Data.Sequence.Internal.ViewL
instance Data.Foldable.Foldable Data.Sequence.Internal.ViewL
instance Data.Traversable.Traversable Data.Sequence.Internal.ViewL
instance GHC.Base.Functor Data.Sequence.Internal.Seq
instance Data.Foldable.Foldable Data.Sequence.Internal.Seq
instance Data.Traversable.Traversable Data.Sequence.Internal.Seq
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Seq a)
instance GHC.Base.Monad Data.Sequence.Internal.Seq
instance Control.Monad.Fix.MonadFix Data.Sequence.Internal.Seq
instance GHC.Base.Applicative Data.Sequence.Internal.Seq
instance GHC.Base.MonadPlus Data.Sequence.Internal.Seq
instance GHC.Base.Alternative Data.Sequence.Internal.Seq
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.Internal.Seq a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.Internal.Seq a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.Internal.Seq a)
instance Data.Functor.Classes.Show1 Data.Sequence.Internal.Seq
instance Data.Functor.Classes.Eq1 Data.Sequence.Internal.Seq
instance Data.Functor.Classes.Ord1 Data.Sequence.Internal.Seq
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.Internal.Seq a)
instance Data.Functor.Classes.Read1 Data.Sequence.Internal.Seq
instance GHC.Base.Monoid (Data.Sequence.Internal.Seq a)
instance GHC.Base.Semigroup (Data.Sequence.Internal.Seq a)
instance GHC.Exts.IsList (Data.Sequence.Internal.Seq a)
instance (a ~ GHC.Types.Char) => Data.String.IsString (Data.Sequence.Internal.Seq a)
instance Control.Monad.Zip.MonadZip Data.Sequence.Internal.Seq
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.Elem a)
instance Data.Sequence.Internal.Sized a => Data.Sequence.Internal.Sized (Data.Sequence.Internal.FingerTree a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.Elem a)
instance GHC.Base.Functor Data.Sequence.Internal.Elem
instance Data.Foldable.Foldable Data.Sequence.Internal.Elem
instance Data.Traversable.Traversable Data.Sequence.Internal.Elem
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Elem a)
instance Data.Foldable.Foldable Data.Sequence.Internal.FingerTree
instance GHC.Base.Functor Data.Sequence.Internal.FingerTree
instance Data.Traversable.Traversable Data.Sequence.Internal.FingerTree
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.FingerTree a)
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.Node a)
instance Data.Foldable.Foldable Data.Sequence.Internal.Node
instance GHC.Base.Functor Data.Sequence.Internal.Node
instance Data.Traversable.Traversable Data.Sequence.Internal.Node
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Node a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.Node a)
instance Data.Foldable.Foldable Data.Sequence.Internal.Digit
instance GHC.Base.Functor Data.Sequence.Internal.Digit
instance Data.Traversable.Traversable Data.Sequence.Internal.Digit
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Digit a)
instance Data.Sequence.Internal.Sized a => Data.Sequence.Internal.Sized (Data.Sequence.Internal.Digit a)
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.ForceBox a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.ForceBox a)


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uThis module provides the various sorting implementations for
°5u<a>Data.Sequence</a>. Further notes are available in the file
°5usorting.md (in this directory).
module Data.Sequence.Internal.Sorting

-- | &lt;math&gt;. <a>sort</a> sorts the specified <a>Seq</a> by the
°5unatural ordering of its elements. The sort is stable. If stability is
°5unot required, <a>unstableSort</a> can be slightly faster.
sort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. <a>sortBy</a> sorts the specified <a>Seq</a> according
°5uto the specified comparator. The sort is stable. If stability is not
°5urequired, <a>unstableSortBy</a> can be slightly faster.
sortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sortOn</a> sorts the specified <a>Seq</a> by
°5ucomparing the results of a key function applied to each element.
°5u<tt><a>sortOn</a> f</tt> is equivalent to <tt><a>sortBy</a>
°5u(<a>compare</a> `<a>on</a>` f)</tt>, but has the performance advantage
°5uof only evaluating <tt>f</tt> once for each element in the input list.
°5uThis is called the decorate-sort-undecorate paradigm, or Schwartzian
°5utransform.
°5u
°5uAn example of using <a>sortOn</a> might be to sort a <a>Seq</a> of
°5ustrings according to their length:
°5u
°5u<pre>
°5usortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
°5u</pre>
°5u
°5uIf, instead, <a>sortBy</a> had been used, <a>length</a> would be
°5uevaluated on every comparison, giving &lt;math&gt; evaluations, rather
°5uthan &lt;math&gt;.
°5u
°5uIf <tt>f</tt> is very cheap (for example a record selector, or
°5u<a>fst</a>), <tt><a>sortBy</a> (<a>compare</a> `<a>on</a>` f)</tt>
°5uwill be faster than <tt><a>sortOn</a> f</tt>.
sortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSort</a> sorts the specified <a>Seq</a> by
°5uthe natural ordering of its elements, but the sort is not stable. This
°5ualgorithm is frequently faster and uses less memory than <a>sort</a>.
unstableSort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. A generalization of <a>unstableSort</a>,
°5u<a>unstableSortBy</a> takes an arbitrary comparator and sorts the
°5uspecified sequence. The sort is not stable. This algorithm is
°5ufrequently faster and uses less memory than <a>sortBy</a>.
unstableSortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSortOn</a> sorts the specified <a>Seq</a> by
°5ucomparing the results of a key function applied to each element.
°5u<tt><a>unstableSortOn</a> f</tt> is equivalent to
°5u<tt><a>unstableSortBy</a> (<a>compare</a> `<a>on</a>` f)</tt>, but has
°5uthe performance advantage of only evaluating <tt>f</tt> once for each
°5uelement in the input list. This is called the decorate-sort-undecorate
°5uparadigm, or Schwartzian transform.
°5u
°5uAn example of using <a>unstableSortOn</a> might be to sort a
°5u<a>Seq</a> of strings according to their length:
°5u
°5u<pre>
°5uunstableSortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
°5u</pre>
°5u
°5uIf, instead, <a>unstableSortBy</a> had been used, <a>length</a> would
°5ube evaluated on every comparison, giving &lt;math&gt; evaluations,
°5urather than &lt;math&gt;.
°5u
°5uIf <tt>f</tt> is very cheap (for example a record selector, or
°5u<a>fst</a>), <tt><a>unstableSortBy</a> (<a>compare</a> `<a>on</a>`
°5uf)</tt> will be faster than <tt><a>unstableSortOn</a> f</tt>.
unstableSortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | A simple pairing heap.
data Queue e
Q :: !e -> (QList e) -> Queue e
data QList e
Nil :: QList e
QCons :: {-# UNPACK #-} !(Queue e) -> (QList e) -> QList e

-- | A pairing heap tagged with the original position of elements, to allow
°5ufor stable sorting.
data IndexedQueue e
IQ :: {-# UNPACK #-} !Int -> !e -> (IQList e) -> IndexedQueue e
data IQList e
IQNil :: IQList e
IQCons :: {-# UNPACK #-} !(IndexedQueue e) -> (IQList e) -> IQList e

-- | A pairing heap tagged with some key for sorting elements, for use in
°5u<a>unstableSortOn</a>.
data TaggedQueue a b
TQ :: !a -> b -> (TQList a b) -> TaggedQueue a b
data TQList a b
TQNil :: TQList a b
TQCons :: {-# UNPACK #-} !(TaggedQueue a b) -> (TQList a b) -> TQList a b

-- | A pairing heap tagged with both a key and the original position of its
°5uelements, for use in <a>sortOn</a>.
data IndexedTaggedQueue e a
ITQ :: {-# UNPACK #-} !Int -> !e -> a -> (ITQList e a) -> IndexedTaggedQueue e a
data ITQList e a
ITQNil :: ITQList e a
ITQCons :: {-# UNPACK #-} !(IndexedTaggedQueue e a) -> (ITQList e a) -> ITQList e a

-- | <a>mergeQ</a> merges two <a>Queue</a>s.
mergeQ :: (a -> a -> Ordering) -> Queue a -> Queue a -> Queue a

-- | <a>mergeIQ</a> merges two <a>IndexedQueue</a>s, taking into account
°5uthe original position of the elements.
mergeIQ :: (a -> a -> Ordering) -> IndexedQueue a -> IndexedQueue a -> IndexedQueue a

-- | <a>mergeTQ</a> merges two <a>TaggedQueue</a>s, based on the tag value.
mergeTQ :: (a -> a -> Ordering) -> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b

-- | <a>mergeITQ</a> merges two <a>IndexedTaggedQueue</a>s, based on the
°5utag value, taking into account the original position of the elements.
mergeITQ :: (a -> a -> Ordering) -> IndexedTaggedQueue a b -> IndexedTaggedQueue a b -> IndexedTaggedQueue a b

-- | Pop the smallest element from the queue, using the supplied
°5ucomparator.
popMinQ :: (e -> e -> Ordering) -> Queue e -> (Queue e, e)

-- | Pop the smallest element from the queue, using the supplied
°5ucomparator, deferring to the item's original position when the
°5ucomparator returns <a>EQ</a>.
popMinIQ :: (e -> e -> Ordering) -> IndexedQueue e -> (IndexedQueue e, e)

-- | Pop the smallest element from the queue, using the supplied comparator
°5uon the tag.
popMinTQ :: (a -> a -> Ordering) -> TaggedQueue a b -> (TaggedQueue a b, b)

-- | Pop the smallest element from the queue, using the supplied comparator
°5uon the tag, deferring to the item's original position when the
°5ucomparator returns <a>EQ</a>.
popMinITQ :: (e -> e -> Ordering) -> IndexedTaggedQueue e b -> (IndexedTaggedQueue e b, b)
buildQ :: (b -> b -> Ordering) -> (a -> Queue b) -> FingerTree a -> Maybe (Queue b)
buildIQ :: (b -> b -> Ordering) -> (Int -> Elem y -> IndexedQueue b) -> Int -> FingerTree (Elem y) -> Maybe (IndexedQueue b)
buildTQ :: (b -> b -> Ordering) -> (a -> TaggedQueue b c) -> FingerTree a -> Maybe (TaggedQueue b c)
buildITQ :: (b -> b -> Ordering) -> (Int -> Elem y -> IndexedTaggedQueue b c) -> Int -> FingerTree (Elem y) -> Maybe (IndexedTaggedQueue b c)

-- | A <a>foldMap</a>-like function, specialized to the <a>Option</a>
°5umonoid, which takes advantage of the internal structure of <a>Seq</a>
°5uto avoid wrapping in <a>Maybe</a> at certain points.
foldToMaybeTree :: (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b

-- | A <tt>foldMapWithIndex</tt>-like function, specialized to the
°5u<a>Option</a> monoid, which takes advantage of the internal structure
°5uof <a>Seq</a> to avoid wrapping in <a>Maybe</a> at certain points.
foldToMaybeWithIndexTree :: (b -> b -> b) -> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b


-- | <h1>Finite sequences</h1>
°5u
°5uThe <tt><a>Seq</a> a</tt> type represents a finite sequence of values
°5uof type <tt>a</tt>.
°5u
°5uSequences generally behave very much like lists.
°5u
°5u<ul>
°5u<li>The class instances for sequences are all based very closely on
°5uthose for lists.</li>
°5u<li>Many functions in this module have the same names as functions in
°5uthe <a>Prelude</a> or in <a>Data.List</a>. In almost all cases, these
°5ufunctions behave analogously. For example, <a>filter</a> filters a
°5usequence in exactly the same way that
°5u<tt><a>Prelude</a>.<a>filter</a></tt> filters a list. The only major
°5uexception is the <a>lookup</a> function, which is based on the
°5ufunction by that name in <a>Data.IntMap</a> rather than the one in
°5u<a>Prelude</a>.</li>
°5u</ul>
°5u
°5uThere are two major differences between sequences and lists:
°5u
°5u<ul>
°5u<li>Sequences support a wider variety of efficient operations than do
°5ulists. Notably, they offer<ul><li>Constant-time access to both the
°5ufront and the rear with <a>&lt;|</a>, <a>|&gt;</a>, <a>viewl</a>,
°5u<a>viewr</a>. For recent GHC versions, this can be done more
°5uconveniently using the bidirectional patterns <a>Empty</a>,
°5u<a>:&lt;|</a>, and <a>:|&gt;</a>. See the detailed explanation in the
°5u"Pattern synonyms" section.</li><li>Logarithmic-time concatenation
°5uwith <a>&gt;&lt;</a></li><li>Logarithmic-time splitting with
°5u<a>splitAt</a>, <a>take</a> and <a>drop</a></li><li>Logarithmic-time
°5uaccess to any element with <a>lookup</a>, <a>!?</a>, <a>index</a>,
°5u<a>insertAt</a>, <a>deleteAt</a>, <a>adjust'</a>, and
°5u<a>update</a></li></ul></li>
°5u</ul>
°5u
°5uNote that sequences are typically <i>slower</i> than lists when using
°5uonly operations for which they have the same big-(O) complexity:
°5usequences make rather mediocre stacks!
°5u
°5u<ul>
°5u<li>Whereas lists can be either finite or infinite, sequences are
°5ualways finite. As a result, a sequence is strict in its length.
°5uIgnoring efficiency, you can imagine that <a>Seq</a> is defined<pre>
°5udata Seq a = Empty | a :&lt;| !(Seq a)</pre>This means that many
°5uoperations on sequences are stricter than those on lists. For
°5uexample,<pre> (1 : undefined) !! 0 = 1</pre>but<pre> (1 :&lt;|
°5uundefined) <a>index</a> 0 = undefined</pre></li>
°5u</ul>
°5u
°5uSequences may also be compared to immutable <a>arrays</a> or
°5u<a>vectors</a>. Like these structures, sequences support fast
°5uindexing, although not as fast. But editing an immutable array or
°5uvector, or combining it with another, generally requires copying the
°5uentire structure; sequences generally avoid that, copying only the
°5uportion that has changed.
°5u
°5u<h2>Detailed performance information</h2>
°5u
°5uAn amortized running time is given for each operation, with <i>n</i>
°5ureferring to the length of the sequence and <i>i</i> being the
°5uintegral index used by some operations. These bounds hold even in a
°5upersistent (shared) setting.
°5u
°5uDespite sequences being structurally strict from a semantic
°5ustandpoint, they are in fact implemented using laziness internally. As
°5ua result, many operations can be performed <i>incrementally</i>,
°5uproducing their results as they are demanded. This greatly improves
°5uperformance in some cases. These functions include
°5u
°5u<ul>
°5u<li>The <a>Functor</a> methods <a>fmap</a> and <a>&lt;$</a>, along
°5uwith <a>mapWithIndex</a></li>
°5u<li>The <a>Applicative</a> methods <a>&lt;*&gt;</a>, <a>*&gt;</a>, and
°5u<a>&lt;*</a></li>
°5u<li>The zips: <a>zipWith</a>, <a>zip</a>, etc.</li>
°5u<li><tt>heads</tt> and <a>tails</a></li>
°5u<li><a>fromFunction</a>, <a>replicate</a>, <a>intersperse</a>, and
°5u<a>cycleTaking</a></li>
°5u<li><a>reverse</a></li>
°5u<li><a>chunksOf</a></li>
°5u</ul>
°5u
°5uNote that the <a>Monad</a> method, <a>&gt;&gt;=</a>, is not
°5uparticularly lazy. It will take time proportional to the sum of the
°5ulogarithms of the individual result sequences to produce anything
°5uwhatsoever.
°5u
°5uSeveral functions take special advantage of sharing to produce results
°5uusing much less time and memory than one might expect. These are
°5udocumented individually for functions, but also include the methods
°5u<a>&lt;$</a> and <a>*&gt;</a>, each of which take time and space
°5uproportional to the logarithm of the size of the result.
°5u
°5u<h2>Warning</h2>
°5u
°5uThe size of a <a>Seq</a> must not exceed <tt>maxBound::Int</tt>.
°5uViolation of this condition is not detected and if the size limit is
°5uexceeded, the behaviour of the sequence is undefined. This is unlikely
°5uto occur in most applications, but some care may be required when
°5uusing <a>&gt;&lt;</a>, <a>&lt;*&gt;</a>, <a>*&gt;</a>, or
°5u<a>&gt;&gt;</a>, particularly repeatedly and particularly in
°5ucombination with <a>replicate</a> or <a>fromFunction</a>.
°5u
°5u<h2>Implementation</h2>
°5u
°5uThe implementation uses 2-3 finger trees annotated with sizes, as
°5udescribed in section 4.2 of
°5u
°5u<ul>
°5u<li>Ralf Hinze and Ross Paterson, <a>"Finger trees: a simple
°5ugeneral-purpose data structure"</a>, <i>Journal of Functional
°5uProgramming</i> 16:2 (2006) pp 197-217.</li>
°5u</ul>
module Data.Sequence

-- | General-purpose finite sequences.
data Seq a

-- | &lt;math&gt;. The empty sequence.
empty :: Seq a

-- | &lt;math&gt;. A singleton sequence.
singleton :: a -> Seq a

-- | &lt;math&gt;. Add an element to the left end of a sequence. Mnemonic:
°5ua triangle with the single element at the pointy end.
(<|) :: a -> Seq a -> Seq a
infixr 5 <|

-- | &lt;math&gt;. Add an element to the right end of a sequence. Mnemonic:
°5ua triangle with the single element at the pointy end.
(|>) :: Seq a -> a -> Seq a
infixl 5 |>

-- | &lt;math&gt;. Concatenate two sequences.
(><) :: Seq a -> Seq a -> Seq a
infixr 5 ><

-- | &lt;math&gt;. Create a sequence from a finite list of elements. There
°5uis a function <a>toList</a> in the opposite direction for all
°5uinstances of the <a>Foldable</a> class, including <a>Seq</a>.
fromList :: [a] -> Seq a

-- | &lt;math&gt;. Convert a given sequence length and a function
°5urepresenting that sequence into a sequence.
fromFunction :: Int -> (Int -> a) -> Seq a

-- | &lt;math&gt;. Create a sequence consisting of the elements of an
°5u<a>Array</a>. Note that the resulting sequence elements may be
°5uevaluated lazily (as on GHC), so you must force the entire structure
°5uto be sure that the original array can be garbage-collected.
fromArray :: Ix i => Array i a -> Seq a

-- | &lt;math&gt;. <tt>replicate n x</tt> is a sequence consisting of
°5u<tt>n</tt> copies of <tt>x</tt>.
replicate :: Int -> a -> Seq a

-- | <a>replicateA</a> is an <a>Applicative</a> version of
°5u<a>replicate</a>, and makes &lt;math&gt; calls to <a>liftA2</a> and
°5u<a>pure</a>.
°5u
°5u<pre>
°5ureplicateA n x = sequenceA (replicate n x)
°5u</pre>
replicateA :: Applicative f => Int -> f a -> f (Seq a)

-- | <a>replicateM</a> is a sequence counterpart of <a>replicateM</a>.
°5u
°5u<pre>
°5ureplicateM n x = sequence (replicate n x)
°5u</pre>
°5u
°5uFor <tt>base &gt;= 4.8.0</tt> and <tt>containers &gt;= 0.5.11</tt>,
°5u<a>replicateM</a> is a synonym for <a>replicateA</a>.
replicateM :: Applicative m => Int -> m a -> m (Seq a)

-- | <i>O(</i>log<i> k)</i>. <tt><a>cycleTaking</a> k xs</tt> forms a
°5usequence of length <tt>k</tt> by repeatedly concatenating <tt>xs</tt>
°5uwith itself. <tt>xs</tt> may only be empty if <tt>k</tt> is 0.
°5u
°5u<pre>
°5ucycleTaking k = fromList . take k . cycle . toList
°5u</pre>
cycleTaking :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Constructs a sequence by repeated application of a
°5ufunction to a seed value.
°5u
°5u<pre>
°5uiterateN n f x = fromList (Prelude.take n (Prelude.iterate f x))
°5u</pre>
iterateN :: Int -> (a -> a) -> a -> Seq a

-- | Builds a sequence from a seed value. Takes time linear in the number
°5uof generated elements. <i>WARNING:</i> If the number of generated
°5uelements is infinite, this method will not terminate.
unfoldr :: (b -> Maybe (a, b)) -> b -> Seq a

-- | <tt><a>unfoldl</a> f x</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>unfoldr</a> (<a>fmap</a> swap . f) x)</tt>.
unfoldl :: (b -> Maybe (b, a)) -> b -> Seq a

-- | &lt;math&gt;. Is this the empty sequence?
null :: Seq a -> Bool

-- | &lt;math&gt;. The number of elements in the sequence.
length :: Seq a -> Int

-- | View of the left end of a sequence.
data ViewL a

-- | empty sequence
EmptyL :: ViewL a

-- | leftmost element and the rest of the sequence
(:<) :: a -> Seq a -> ViewL a

-- | &lt;math&gt;. Analyse the left end of a sequence.
viewl :: Seq a -> ViewL a

-- | View of the right end of a sequence.
data ViewR a

-- | empty sequence
EmptyR :: ViewR a

-- | the sequence minus the rightmost element, and the rightmost element
(:>) :: Seq a -> a -> ViewR a

-- | &lt;math&gt;. Analyse the right end of a sequence.
viewr :: Seq a -> ViewR a

-- | <a>scanl</a> is similar to <a>foldl</a>, but returns a sequence of
°5ureduced values from the left:
°5u
°5u<pre>
°5uscanl f z (fromList [x1, x2, ...]) = fromList [z, z `f` x1, (z `f` x1) `f` x2, ...]
°5u</pre>
scanl :: (a -> b -> a) -> a -> Seq b -> Seq a

-- | <a>scanl1</a> is a variant of <a>scanl</a> that has no starting value
°5uargument:
°5u
°5u<pre>
°5uscanl1 f (fromList [x1, x2, ...]) = fromList [x1, x1 `f` x2, ...]
°5u</pre>
scanl1 :: (a -> a -> a) -> Seq a -> Seq a

-- | <a>scanr</a> is the right-to-left dual of <a>scanl</a>.
scanr :: (a -> b -> b) -> b -> Seq a -> Seq b

-- | <a>scanr1</a> is a variant of <a>scanr</a> that has no starting value
°5uargument.
scanr1 :: (a -> a -> a) -> Seq a -> Seq a

-- | &lt;math&gt;. Returns a sequence of all suffixes of this sequence,
°5ulongest first. For example,
°5u
°5u<pre>
°5utails (fromList "abc") = fromList [fromList "abc", fromList "bc", fromList "c", fromList ""]
°5u</pre>
°5u
°5uEvaluating the &lt;math&gt;th suffix takes &lt;math&gt;, but
°5uevaluating every suffix in the sequence takes &lt;math&gt; due to
°5usharing.
tails :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. Returns a sequence of all prefixes of this sequence,
°5ushortest first. For example,
°5u
°5u<pre>
°5uinits (fromList "abc") = fromList [fromList "", fromList "a", fromList "ab", fromList "abc"]
°5u</pre>
°5u
°5uEvaluating the &lt;math&gt;th prefix takes &lt;math&gt;, but
°5uevaluating every prefix in the sequence takes &lt;math&gt; due to
°5usharing.
inits :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. <tt>chunksOf c xs</tt> splits <tt>xs</tt> into chunks of
°5usize <tt>c&gt;0</tt>. If <tt>c</tt> does not divide the length of
°5u<tt>xs</tt> evenly, then the last element of the result will be short.
°5u
°5uSide note: the given performance bound is missing some messy terms
°5uthat only really affect edge cases. Performance degrades smoothly from
°5u&lt;math&gt; (for &lt;math&gt;) to &lt;math&gt; (for &lt;math&gt;).
°5uThe true bound is more like &lt;math&gt;
chunksOf :: Int -> Seq a -> Seq (Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
°5u<a>takeWhileL</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns the longest prefix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt>.
takeWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
°5u<a>takeWhileR</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns the longest suffix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt>.
°5u
°5u<tt><a>takeWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>takeWhileL</a> p (<a>reverse</a> xs))</tt>.
takeWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
°5u<tt><a>dropWhileL</a> p xs</tt> returns the suffix remaining after
°5u<tt><a>takeWhileL</a> p xs</tt>.
dropWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
°5u<tt><a>dropWhileR</a> p xs</tt> returns the prefix remaining after
°5u<tt><a>takeWhileR</a> p xs</tt>.
°5u
°5u<tt><a>dropWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
°5u(<a>dropWhileL</a> p (<a>reverse</a> xs))</tt>.
dropWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length. <a>spanl</a>,
°5uapplied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
°5ua pair whose first element is the longest prefix (possibly empty) of
°5u<tt>xs</tt> of elements that satisfy <tt>p</tt> and the second element
°5uis the remainder of the sequence.
spanl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the suffix length. <a>spanr</a>,
°5uapplied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
°5ua pair whose <i>first</i> element is the longest <i>suffix</i>
°5u(possibly empty) of <tt>xs</tt> of elements that satisfy <tt>p</tt>
°5uand the second element is the remainder of the sequence.
spanr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the breakpoint index.
°5u<a>breakl</a>, applied to a predicate <tt>p</tt> and a sequence
°5u<tt>xs</tt>, returns a pair whose first element is the longest prefix
°5u(possibly empty) of <tt>xs</tt> of elements that <i>do not satisfy</i>
°5u<tt>p</tt> and the second element is the remainder of the sequence.
°5u
°5u<tt><a>breakl</a> p</tt> is equivalent to <tt><a>spanl</a> (not .
°5up)</tt>.
breakl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | <tt><a>breakr</a> p</tt> is equivalent to <tt><a>spanr</a> (not .
°5up)</tt>.
breakr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>partition</a> function takes a predicate
°5u<tt>p</tt> and a sequence <tt>xs</tt> and returns sequences of those
°5uelements which do and do not satisfy the predicate.
partition :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>filter</a> function takes a predicate <tt>p</tt>
°5uand a sequence <tt>xs</tt> and returns a sequence of those elements
°5uwhich satisfy the predicate.
filter :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sort</a> sorts the specified <a>Seq</a> by the
°5unatural ordering of its elements. The sort is stable. If stability is
°5unot required, <a>unstableSort</a> can be slightly faster.
sort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. <a>sortBy</a> sorts the specified <a>Seq</a> according
°5uto the specified comparator. The sort is stable. If stability is not
°5urequired, <a>unstableSortBy</a> can be slightly faster.
sortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sortOn</a> sorts the specified <a>Seq</a> by
°5ucomparing the results of a key function applied to each element.
°5u<tt><a>sortOn</a> f</tt> is equivalent to <tt><a>sortBy</a>
°5u(<a>compare</a> `<a>on</a>` f)</tt>, but has the performance advantage
°5uof only evaluating <tt>f</tt> once for each element in the input list.
°5uThis is called the decorate-sort-undecorate paradigm, or Schwartzian
°5utransform.
°5u
°5uAn example of using <a>sortOn</a> might be to sort a <a>Seq</a> of
°5ustrings according to their length:
°5u
°5u<pre>
°5usortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
°5u</pre>
°5u
°5uIf, instead, <a>sortBy</a> had been used, <a>length</a> would be
°5uevaluated on every comparison, giving &lt;math&gt; evaluations, rather
°5uthan &lt;math&gt;.
°5u
°5uIf <tt>f</tt> is very cheap (for example a record selector, or
°5u<a>fst</a>), <tt><a>sortBy</a> (<a>compare</a> `<a>on</a>` f)</tt>
°5uwill be faster than <tt><a>sortOn</a> f</tt>.
sortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSort</a> sorts the specified <a>Seq</a> by
°5uthe natural ordering of its elements, but the sort is not stable. This
°5ualgorithm is frequently faster and uses less memory than <a>sort</a>.
unstableSort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. A generalization of <a>unstableSort</a>,
°5u<a>unstableSortBy</a> takes an arbitrary comparator and sorts the
°5uspecified sequence. The sort is not stable. This algorithm is
°5ufrequently faster and uses less memory than <a>sortBy</a>.
unstableSortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSortOn</a> sorts the specified <a>Seq</a> by
°5ucomparing the results of a key function applied to each element.
°5u<tt><a>unstableSortOn</a> f</tt> is equivalent to
°5u<tt><a>unstableSortBy</a> (<a>compare</a> `<a>on</a>` f)</tt>, but has
°5uthe performance advantage of only evaluating <tt>f</tt> once for each
°5uelement in the input list. This is called the decorate-sort-undecorate
°5uparadigm, or Schwartzian transform.
°5u
°5uAn example of using <a>unstableSortOn</a> might be to sort a
°5u<a>Seq</a> of strings according to their length:
°5u
°5u<pre>
°5uunstableSortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
°5u</pre>
°5u
°5uIf, instead, <a>unstableSortBy</a> had been used, <a>length</a> would
°5ube evaluated on every comparison, giving &lt;math&gt; evaluations,
°5urather than &lt;math&gt;.
°5u
°5uIf <tt>f</tt> is very cheap (for example a record selector, or
°5u<a>fst</a>), <tt><a>unstableSortBy</a> (<a>compare</a> `<a>on</a>`
°5uf)</tt> will be faster than <tt><a>unstableSortOn</a> f</tt>.
unstableSortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
°5uIf the specified position is negative or at least the length of the
°5usequence, <a>lookup</a> returns <a>Nothing</a>.
°5u
°5u<pre>
°5u0 &lt;= i &lt; length xs ==&gt; lookup i xs == Just (toList xs !! i)
°5u</pre>
°5u
°5u<pre>
°5ui &lt; 0 || i &gt;= length xs ==&gt; lookup i xs = Nothing
°5u</pre>
°5u
°5uUnlike <a>index</a>, this can be used to retrieve an element without
°5uforcing it. For example, to insert the fifth element of a sequence
°5u<tt>xs</tt> into a <a>Map</a> <tt>m</tt> at key <tt>k</tt>, you could
°5uuse
°5u
°5u<pre>
°5ucase lookup 5 xs of
°5u  Nothing -&gt; m
°5u  Just x -&gt; <a>insert</a> k x m
°5u</pre>
lookup :: Int -> Seq a -> Maybe a

-- | &lt;math&gt;. A flipped, infix version of <a>lookup</a>.
(!?) :: Seq a -> Int -> Maybe a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
°5uThe argument should thus be a non-negative integer less than the size
°5uof the sequence. If the position is out of range, <a>index</a> fails
°5uwith an error.
°5u
°5u<pre>
°5uxs `index` i = toList xs !! i
°5u</pre>
°5u
°5uCaution: <a>index</a> necessarily delays retrieving the requested
°5uelement until the result is forced. It can therefore lead to a space
°5uleak if the result is stored, unforced, in another structure. To
°5uretrieve an element immediately without forcing it, use <a>lookup</a>
°5uor '(!?)'.
index :: Seq a -> Int -> a

-- | &lt;math&gt;. Update the element at the specified position. If the
°5uposition is out of range, the original sequence is returned.
°5u<a>adjust</a> can lead to poor performance and even memory leaks,
°5ubecause it does not force the new value before installing it in the
°5usequence. <a>adjust'</a> should usually be preferred.
adjust :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Update the element at the specified position. If the
°5uposition is out of range, the original sequence is returned. The new
°5uvalue is forced before it is installed in the sequence.
°5u
°5u<pre>
°5uadjust' f i xs =
°5u case xs !? i of
°5u   Nothing -&gt; xs
°5u   Just x -&gt; let !x' = f x
°5u             in update i x' xs
°5u</pre>
adjust' :: forall a. (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Replace the element at the specified position. If the
°5uposition is out of range, the original sequence is returned.
update :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. The first <tt>i</tt> elements of a sequence. If
°5u<tt>i</tt> is negative, <tt><a>take</a> i s</tt> yields the empty
°5usequence. If the sequence contains fewer than <tt>i</tt> elements, the
°5uwhole sequence is returned.
take :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Elements of a sequence after the first <tt>i</tt>. If
°5u<tt>i</tt> is negative, <tt><a>drop</a> i s</tt> yields the whole
°5usequence. If the sequence contains fewer than <tt>i</tt> elements, the
°5uempty sequence is returned.
drop :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. <tt><a>insertAt</a> i x xs</tt> inserts <tt>x</tt> into
°5u<tt>xs</tt> at the index <tt>i</tt>, shifting the rest of the sequence
°5uover.
°5u
°5u<pre>
°5uinsertAt 2 x (fromList [a,b,c,d]) = fromList [a,b,x,c,d]
°5uinsertAt 4 x (fromList [a,b,c,d]) = insertAt 10 x (fromList [a,b,c,d])
°5u                                  = fromList [a,b,c,d,x]
°5u</pre>
°5u
°5u<pre>
°5uinsertAt i x xs = take i xs &gt;&lt; singleton x &gt;&lt; drop i xs
°5u</pre>
insertAt :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. Delete the element of a sequence at a given index.
°5uReturn the original sequence if the index is out of range.
°5u
°5u<pre>
°5udeleteAt 2 [a,b,c,d] = [a,b,d]
°5udeleteAt 4 [a,b,c,d] = deleteAt (-1) [a,b,c,d] = [a,b,c,d]
°5u</pre>
deleteAt :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Split a sequence at a given position. <tt><a>splitAt</a>
°5ui s = (<a>take</a> i s, <a>drop</a> i s)</tt>.
splitAt :: Int -> Seq a -> (Seq a, Seq a)

-- | <a>elemIndexL</a> finds the leftmost index of the specified element,
°5uif it is present, and otherwise <a>Nothing</a>.
elemIndexL :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesL</a> finds the indices of the specified element, from
°5uleft to right (i.e. in ascending order).
elemIndicesL :: Eq a => a -> Seq a -> [Int]

-- | <a>elemIndexR</a> finds the rightmost index of the specified element,
°5uif it is present, and otherwise <a>Nothing</a>.
elemIndexR :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesR</a> finds the indices of the specified element, from
°5uright to left (i.e. in descending order).
elemIndicesR :: Eq a => a -> Seq a -> [Int]

-- | <tt><a>findIndexL</a> p xs</tt> finds the index of the leftmost
°5uelement that satisfies <tt>p</tt>, if any exist.
findIndexL :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesL</a> p</tt> finds all indices of elements that
°5usatisfy <tt>p</tt>, in ascending order.
findIndicesL :: (a -> Bool) -> Seq a -> [Int]

-- | <tt><a>findIndexR</a> p xs</tt> finds the index of the rightmost
°5uelement that satisfies <tt>p</tt>, if any exist.
findIndexR :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesR</a> p</tt> finds all indices of elements that
°5usatisfy <tt>p</tt>, in descending order.
findIndicesR :: (a -> Bool) -> Seq a -> [Int]
foldMapWithIndex :: Monoid m => (Int -> a -> m) -> Seq a -> m

-- | <a>foldlWithIndex</a> is a version of <a>foldl</a> that also provides
°5uaccess to the index of each element.
foldlWithIndex :: (b -> Int -> a -> b) -> b -> Seq a -> b

-- | <a>foldrWithIndex</a> is a version of <a>foldr</a> that also provides
°5uaccess to the index of each element.
foldrWithIndex :: (Int -> a -> b -> b) -> b -> Seq a -> b

-- | A generalization of <a>fmap</a>, <a>mapWithIndex</a> takes a mapping
°5ufunction that also depends on the element's index, and applies it to
°5uevery element in the sequence.
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b

-- | <a>traverseWithIndex</a> is a version of <a>traverse</a> that also
°5uoffers access to the index of each element.
traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)

-- | &lt;math&gt;. The reverse of a sequence.
reverse :: Seq a -> Seq a

-- | &lt;math&gt;. Intersperse an element between the elements of a
°5usequence.
°5u
°5u<pre>
°5uintersperse a empty = empty
°5uintersperse a (singleton x) = singleton x
°5uintersperse a (fromList [x,y]) = fromList [x,a,y]
°5uintersperse a (fromList [x,y,z]) = fromList [x,a,y,a,z]
°5u</pre>
intersperse :: a -> Seq a -> Seq a

-- | &lt;math&gt;. <a>zip</a> takes two sequences and returns a sequence of
°5ucorresponding pairs. If one input is short, excess elements are
°5udiscarded from the right end of the longer sequence.
zip :: Seq a -> Seq b -> Seq (a, b)

-- | &lt;math&gt;. <a>zipWith</a> generalizes <a>zip</a> by zipping with
°5uthe function given as the first argument, instead of a tupling
°5ufunction. For example, <tt>zipWith (+)</tt> is applied to two
°5usequences to take the sequence of corresponding sums.
zipWith :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip3</a> takes three sequences and returns a sequence
°5uof triples, analogous to <a>zip</a>.
zip3 :: Seq a -> Seq b -> Seq c -> Seq (a, b, c)

-- | &lt;math&gt;. <a>zipWith3</a> takes a function which combines three
°5uelements, as well as three sequences and returns a sequence of their
°5upoint-wise combinations, analogous to <a>zipWith</a>.
zipWith3 :: (a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d

-- | &lt;math&gt;. <a>zip4</a> takes four sequences and returns a sequence
°5uof quadruples, analogous to <a>zip</a>.
zip4 :: Seq a -> Seq b -> Seq c -> Seq d -> Seq (a, b, c, d)

-- | &lt;math&gt;. <a>zipWith4</a> takes a function which combines four
°5uelements, as well as four sequences and returns a sequence of their
°5upoint-wise combinations, analogous to <a>zipWith</a>.
zipWith4 :: (a -> b -> c -> d -> e) -> Seq a -> Seq b -> Seq c -> Seq d -> Seq e

-- | Unzip a sequence of pairs.
°5u
°5u<pre>
°5uunzip ps = ps `<tt>seq'</tt> (<a>fmap</a> <a>fst</a> ps) (<a>fmap</a> <a>snd</a> ps)
°5u</pre>
°5u
°5uExample:
°5u
°5u<pre>
°5uunzip $ fromList [(1,"a"), (2,"b"), (3,"c")] =
°5u  (fromList [1,2,3], fromList ["a", "b", "c"])
°5u</pre>
°5u
°5uSee the note about efficiency at <a>unzipWith</a>.
unzip :: Seq (a, b) -> (Seq a, Seq b)

-- | &lt;math&gt;. Unzip a sequence using a function to divide elements.
°5u
°5u<pre>
°5uunzipWith f xs == <a>unzip</a> (<a>fmap</a> f xs)
°5u</pre>
°5u
°5uEfficiency note:
°5u
°5u<tt>unzipWith</tt> produces its two results in lockstep. If you
°5ucalculate <tt> unzipWith f xs </tt> and fully force <i>either</i> of
°5uthe results, then the entire structure of the <i>other</i> one will be
°5ubuilt as well. This behavior allows the garbage collector to collect
°5ueach calculated pair component as soon as it dies, without having to
°5uwait for its mate to die. If you do not need this behavior, you may be
°5ubetter off simply calculating the sequence of pairs and using
°5u<a>fmap</a> to extract each component sequence.
unzipWith :: (a -> (b, c)) -> Seq a -> (Seq b, Seq c)


-- | Multi-way trees (<i>aka</i> rose trees) and forests.
module Data.Tree

-- | Multi-way trees, also known as <i>rose trees</i>.
data Tree a
Node :: a -> Forest a -> Tree a

-- | label value
[rootLabel] :: Tree a -> a

-- | zero or more child trees
[subForest] :: Tree a -> Forest a
type Forest a = [Tree a]

-- | Neat 2-dimensional drawing of a tree.
drawTree :: Tree String -> String

-- | Neat 2-dimensional drawing of a forest.
drawForest :: Forest String -> String

-- | The elements of a tree in pre-order.
flatten :: Tree a -> [a]

-- | Lists of nodes at each level of the tree.
levels :: Tree a -> [[a]]

-- | Catamorphism on trees.
foldTree :: (a -> [b] -> b) -> Tree a -> b

-- | Build a tree from a seed value
unfoldTree :: (b -> (a, [b])) -> b -> Tree a

-- | Build a forest from a list of seed values
unfoldForest :: (b -> (a, [b])) -> [b] -> Forest a

-- | Monadic tree builder, in depth-first order
unfoldTreeM :: Monad m => (b -> m (a, [b])) -> b -> m (Tree a)

-- | Monadic forest builder, in depth-first order
unfoldForestM :: Monad m => (b -> m (a, [b])) -> [b] -> m (Forest a)

-- | Monadic tree builder, in breadth-first order, using an algorithm
°5uadapted from <i>Breadth-First Numbering: Lessons from a Small Exercise
°5uin Algorithm Design</i>, by Chris Okasaki, <i>ICFP'00</i>.
unfoldTreeM_BF :: Monad m => (b -> m (a, [b])) -> b -> m (Tree a)

-- | Monadic forest builder, in breadth-first order, using an algorithm
°5uadapted from <i>Breadth-First Numbering: Lessons from a Small Exercise
°5uin Algorithm Design</i>, by Chris Okasaki, <i>ICFP'00</i>.
unfoldForestM_BF :: Monad m => (b -> m (a, [b])) -> [b] -> m (Forest a)
instance GHC.Generics.Generic1 Data.Tree.Tree
instance GHC.Generics.Generic (Data.Tree.Tree a)
instance Data.Data.Data a => Data.Data.Data (Data.Tree.Tree a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Tree a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Tree.Tree a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Tree a)
instance Data.Functor.Classes.Eq1 Data.Tree.Tree
instance Data.Functor.Classes.Ord1 Data.Tree.Tree
instance Data.Functor.Classes.Show1 Data.Tree.Tree
instance Data.Functor.Classes.Read1 Data.Tree.Tree
instance GHC.Base.Functor Data.Tree.Tree
instance GHC.Base.Applicative Data.Tree.Tree
instance GHC.Base.Monad Data.Tree.Tree
instance Control.Monad.Fix.MonadFix Data.Tree.Tree
instance Data.Traversable.Traversable Data.Tree.Tree
instance Data.Foldable.Foldable Data.Tree.Tree
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Tree.Tree a)
instance Control.Monad.Zip.MonadZip Data.Tree.Tree


-- | A version of the graph algorithms described in:
°5u
°5u<i>Structuring Depth-First Search Algorithms in Haskell</i>, by David
°5uKing and John Launchbury.
module Data.Graph

-- | The strongly connected components of a directed graph, topologically
°5usorted.
stronglyConnComp :: Ord key => [(node, key, [key])] -> [SCC node]

-- | The strongly connected components of a directed graph, topologically
°5usorted. The function is the same as <a>stronglyConnComp</a>, except
°5uthat all the information about each node retained. This interface is
°5uused when you expect to apply <a>SCC</a> to (some of) the result of
°5u<a>SCC</a>, so you don't want to lose the dependency information.
stronglyConnCompR :: Ord key => [(node, key, [key])] -> [SCC (node, key, [key])]

-- | Strongly connected component.
data SCC vertex

-- | A single vertex that is not in any cycle.
AcyclicSCC :: vertex -> SCC vertex

-- | A maximal set of mutually reachable vertices.
CyclicSCC :: [vertex] -> SCC vertex

-- | The vertices of a strongly connected component.
flattenSCC :: SCC vertex -> [vertex]

-- | The vertices of a list of strongly connected components.
flattenSCCs :: [SCC a] -> [a]

-- | Adjacency list representation of a graph, mapping each vertex to its
°5ulist of successors.
type Graph = Table [Vertex]

-- | Table indexed by a contiguous set of vertices.
type Table a = Array Vertex a

-- | The bounds of a <a>Table</a>.
type Bounds = (Vertex, Vertex)

-- | An edge from the first vertex to the second.
type Edge = (Vertex, Vertex)

-- | Abstract representation of vertices.
type Vertex = Int

-- | Build a graph from a list of nodes uniquely identified by keys, with a
°5ulist of keys of nodes this node should have edges to. The out-list may
°5ucontain keys that don't correspond to nodes of the graph; they are
°5uignored.
graphFromEdges :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)

-- | Identical to <a>graphFromEdges</a>, except that the return value does
°5unot include the function which maps keys to vertices. This version of
°5u<a>graphFromEdges</a> is for backwards compatibility.
graphFromEdges' :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]))

-- | Build a graph from a list of edges.
buildG :: Bounds -> [Edge] -> Graph

-- | The graph obtained by reversing all edges.
transposeG :: Graph -> Graph

-- | All vertices of a graph.
vertices :: Graph -> [Vertex]

-- | All edges of a graph.
edges :: Graph -> [Edge]

-- | A table of the count of edges from each node.
outdegree :: Graph -> Table Int

-- | A table of the count of edges into each node.
indegree :: Graph -> Table Int

-- | A spanning forest of the part of the graph reachable from the listed
°5uvertices, obtained from a depth-first search of the graph starting at
°5ueach of the listed vertices in order.
dfs :: Graph -> [Vertex] -> Forest Vertex

-- | A spanning forest of the graph, obtained from a depth-first search of
°5uthe graph starting from each vertex in an unspecified order.
dff :: Graph -> Forest Vertex

-- | A topological sort of the graph. The order is partially specified by
°5uthe condition that a vertex <i>i</i> precedes <i>j</i> whenever
°5u<i>j</i> is reachable from <i>i</i> but not vice versa.
topSort :: Graph -> [Vertex]

-- | The connected components of a graph. Two vertices are connected if
°5uthere is a path between them, traversing edges in either direction.
components :: Graph -> Forest Vertex

-- | The strongly connected components of a graph.
scc :: Graph -> Forest Vertex

-- | The biconnected components of a graph. An undirected graph is
°5ubiconnected if the deletion of any vertex leaves it connected.
bcc :: Graph -> Forest [Vertex]

-- | A list of vertices reachable from a given vertex.
reachable :: Graph -> Vertex -> [Vertex]

-- | Is the second vertex reachable from the first?
path :: Graph -> Vertex -> Vertex -> Bool
type Forest a = [Tree a]

-- | Multi-way trees, also known as <i>rose trees</i>.
data Tree a
Node :: a -> Forest a -> Tree a
instance GHC.Read.Read vertex => GHC.Read.Read (Data.Graph.SCC vertex)
instance GHC.Show.Show vertex => GHC.Show.Show (Data.Graph.SCC vertex)
instance GHC.Classes.Eq vertex => GHC.Classes.Eq (Data.Graph.SCC vertex)
instance Data.Data.Data vertex => Data.Data.Data (Data.Graph.SCC vertex)
instance GHC.Generics.Generic1 Data.Graph.SCC
instance GHC.Generics.Generic (Data.Graph.SCC vertex)
instance GHC.Base.Monad (Data.Graph.SetM s)
instance GHC.Base.Functor (Data.Graph.SetM s)
instance GHC.Base.Applicative (Data.Graph.SetM s)
instance Data.Functor.Classes.Eq1 Data.Graph.SCC
instance Data.Functor.Classes.Show1 Data.Graph.SCC
instance Data.Functor.Classes.Read1 Data.Graph.SCC
instance Data.Foldable.Foldable Data.Graph.SCC
instance Data.Traversable.Traversable Data.Graph.SCC
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Graph.SCC a)
instance GHC.Base.Functor Data.Graph.SCC


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uAn efficient implementation of maps from keys to values
°5u(dictionaries).
°5u
°5uSince many function names (but not the type name) clash with
°5u<a>Prelude</a> names, this module is usually imported
°5u<tt>qualified</tt>, e.g.
°5u
°5u<pre>
°5uimport Data.Map (Map)
°5uimport qualified Data.Map as Map
°5u</pre>
°5u
°5uThe implementation of <a>Map</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
°5u
°5uNote that the implementation is <i>left-biased</i> -- the elements of
°5ua first argument are always preferred to the second, for example in
°5u<a>union</a> or <a>insert</a>.
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>.
module Data.Map.Internal

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a
Bin :: {-# UNPACK #-} !Size -> !k -> a -> !(Map k a) -> !(Map k a) -> Map k a
Tip :: Map k a
type Size = Int

-- | <i>O(log n)</i>. Find the value at a key. Calls <a>error</a> when the
°5uelement can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | <i>O(log n)</i>. Find the value at a key. Returns <a>Nothing</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
°5u</pre>
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.Map.null (empty)           == True
°5uData.Map.null (singleton 1 'a') == False
°5u</pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. The number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: Map k a -> Int

-- | <i>O(log n)</i>. Is the key a member of the map? See also
°5u<a>notMember</a>.
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Is the key not a member of the map? See also
°5u<a>member</a>.
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Lookup the value at a key in the map.
°5u
°5uThe function will return the corresponding value as <tt>(<a>Just</a>
°5uvalue)</tt>, or <a>Nothing</a> if the key isn't in the map.
°5u
°5uAn example of using <tt>lookup</tt>:
°5u
°5u<pre>
°5uimport Prelude hiding (lookup)
°5uimport Data.Map
°5u
°5uemployeeDept = fromList([("John","Sales"), ("Bob","IT")])
°5udeptCountry = fromList([("IT","USA"), ("Sales","France")])
°5ucountryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
°5u
°5uemployeeCurrency :: String -&gt; Maybe String
°5uemployeeCurrency name = do
°5u    dept &lt;- lookup name employeeDept
°5u    country &lt;- lookup dept deptCountry
°5u    lookup country countryCurrency
°5u
°5umain = do
°5u    putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
°5u    putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
°5u</pre>
°5u
°5uThe output of this program:
°5u
°5u<pre>
°5uJohn's currency: Just "Euro"
°5uPete's currency: Nothing
°5u</pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | <i>O(log n)</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns default value
°5u<tt>def</tt> when the key is not in the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: Map k a

-- | <i>O(1)</i>. A map with a single element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: k -> a -> Map k a

-- | <i>O(log n)</i>. Insert a new key and value in the map. If the key is
°5ualready present in the map, the associated value is replaced with the
°5usupplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
°5u<a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining new value and old
°5uvalue. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert the pair <tt>(key, f
°5unew_value old_value)</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining key, new value and
°5uold value. <tt><a>insertWithKey</a> f key value mp</tt> will insert
°5uthe pair (key, value) into <tt>mp</tt> if key does not exist in the
°5umap. If the key does exist, the function will insert the pair
°5u<tt>(key,f key new_value old_value)</tt>. Note that the key passed to
°5uf is the same key passed to <a>insertWithKey</a>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Combines insert operation with old value retrieval.
°5uThe expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a
°5upair where the first element is equal to (<tt><a>lookup</a> k
°5umap</tt>) and the second element equal to (<tt><a>insertWithKey</a> f
°5uk x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. Delete a key and its value from the map. When the key
°5uis not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update a value at a specific key with the result of
°5uthe provided function. When the key is not a member of the map, the
°5uoriginal map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Adjust a value at a specific key. When the key is not
°5ua member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>updateWithKey</a> f k
°5umap</tt>) updates the value <tt>x</tt> at <tt>k</tt> (if it is in the
°5umap). If (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted.
°5uIf it is (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the
°5unew value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
°5ufunction returns changed value, if it is updated. Returns the original
°5ukey value if the map entry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>alter</a> f k map</tt>) alters
°5uthe value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
°5ucan be used to insert, delete, or update a value in a <a>Map</a>. In
°5ushort : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
°5um)</tt>.
°5u
°5u<pre>
°5ulet f _ = Nothing
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u
°5ulet f _ = Just "c"
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
°5u</pre>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in a <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt;
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map. When used with
°5utrivial functors like <a>Identity</a> and <a>Const</a>, it is often
°5uslightly slower than more specialized combinators like <a>lookup</a>
°5uand <a>insert</a>. However, when the functor is non-trivial and key
°5ucomparison is not particularly cheap, it is the fastest way.
°5u
°5uNote on rewrite rules:
°5u
°5uThis module includes GHC rewrite rules to optimize <a>alterF</a> for
°5uthe <a>Const</a> and <a>Identity</a> functors. In general, these rules
°5uimprove performance. The sole exception is that when using
°5u<a>Identity</a>, deleting a key that is already absent takes longer
°5uthan it would without the rules. If you expect this to occur a very
°5ularge fraction of the time, you might consider using a private copy of
°5uthe <a>Identity</a> type.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression (<tt><a>union</a>
°5ut1 t2</tt>) takes the left-biased union of <tt>t1</tt> and
°5u<tt>t2</tt>. It prefers <tt>t1</tt> when duplicate keys are
°5uencountered, i.e. (<tt><a>union</a> == <a>unionWith</a>
°5u<a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: Ord k => [Map k a] -> Map k a

-- | The union of a list of maps, with a combining operation:
°5u(<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
°5u<a>empty</a></tt>).
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two maps. Return
°5uelements of the first map not existing in the second map.
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the values
°5uof these keys. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection of two maps. Return
°5udata in the first map for the keys existing in both maps.
°5u(<tt><a>intersection</a> m1 m2 == <a>intersectionWith</a> <a>const</a>
°5um1 m2</tt>).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; Maybe z
°5u</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt;
°5uMaybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
°5u                    -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
°5u               -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMatched :: Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMissing f k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
°5u</tt>.
data WhenMissing f k x y
WhenMissing :: Map k x -> f (Map k y) -> k -> x -> f (Maybe y) -> WhenMissing f k x y
[missingSubtree] :: WhenMissing f k x y -> Map k x -> f (Map k y)
[missingKey] :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
°5u(Maybe z) </tt>.
newtype WhenMatched f k x y z
WhenMatched :: k -> x -> y -> f (Maybe z) -> WhenMatched f k x y z
[matchedKey] :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  k x -&gt; (b -&gt; guard b *&gt; Just x) <a>$</a> f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | <i>O(n+m)</i>. An unsafe general combining function.
°5u
°5uWARNING: This function can produce corrupt maps and its results may
°5udepend on the internal structures of its inputs. Users should prefer
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>Map</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt>,
°5u<tt><a>filterWithKey</a> f</tt>, or <tt><a>mapMaybeWithKey</a> f</tt>
°5ucould be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
°5u(<a>toList</a> m)</tt> That is, behaves exactly like a regular
°5u<a>traverse</a> except that the traversing function also has access to
°5uthe key associated with a value.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. Traverse keys/values and collect the <a>Just</a> results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | <i>O(n)</i>. The function <a>mapAccum</a> threads an accumulating
°5uargument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <a>mapAccumWithKey</a> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> threads an accumulating
°5uargument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n*log n)</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained by
°5uapplying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>. The value at the greater of the two
°5uoriginal keys is used as the first argument to <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
°5us</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
°5ufor any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
°5u<tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The precondition is
°5unot checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5uvalid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
°5uvalid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
°5u</pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: Map k a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: Map k a -> [k]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Return all key/value pairs
°5uin the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
°5ukeysSet empty == Data.Set.empty
°5u</pre>
keysSet :: Map k a -> Set k

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.Set.empty == empty
°5u</pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: Map k a -> [(k, a)]

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs. See
°5ualso <a>fromAscList</a>. If the list contains more than one value for
°5uthe same key, the last value for the key is retained.
°5u
°5uIf the keys of the list are ordered, linear-time implementation is
°5uused, with the performance equal to <a>fromDistinctAscList</a>.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWithKey</a>.
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ a1 ++ a2
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
°5uvalid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
°5u</pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
°5ufromDescList [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
°5uvalid (fromDistinctDescList [(5,"a"), (5,"b"), (3,"b")]) == False
°5u</pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Filter all values that satisfy the predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | <i>O(n)</i>. Filter all keys/values that satisfy the predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Take while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
°5utakeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
°5u</pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Drop while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
°5udropWhileAntitone p = <a>filterWithKey</a> (k -&gt; not (p k))
°5u</pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Divide a map at the point where a predicate on the
°5ukeys stops holding. The user is responsible for ensuring that for all
°5ukeys <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j
°5u&gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first key and to fail after
°5uthe last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Restrict a <a>Map</a> to only
°5uthose keys found in a <a>Set</a>.
°5u
°5u<pre>
°5um `<tt>restrictKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5um `<tt>restrictKeys'</tt> s = m `<tt>intersect</tt> <a>fromSet</a> (const ()) s
°5u</pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Remove all keys in a <a>Set</a>
°5ufrom a <a>Map</a>.
°5u
°5u<pre>
°5um `<tt>withoutKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5um `<tt>withoutKeys'</tt> s = m `<tt>difference'</tt> <a>fromSet</a> (const ()) s
°5u</pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller
°5uthan <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>splitLookup</a> k map</tt>)
°5usplits a map just like <a>split</a> but also returns <tt><a>lookup</a>
°5uk map</tt>.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. This function is defined as
°5u(<tt><a>isSubmapOf</a> = <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression
°5u(<tt><a>isSubmapOfBy</a> f t1 t2</tt>) returns <a>True</a> if all keys
°5uin <tt>t1</tt> are in tree <tt>t2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
°5u</pre>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). Defined as (<tt><a>isProperSubmapOf</a> =
°5u<a>isProperSubmapOfBy</a> (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). The expression (<tt><a>isProperSubmapOfBy</a> f
°5um1 m2</tt>) returns <a>True</a> when <tt>m1</tt> and <tt>m2</tt> are
°5unot equal, all keys in <tt>m1</tt> are in <tt>m2</tt>, and when
°5u<tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(log n)</i>. Lookup the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5u
°5u<pre>
°5uisJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
°5ufromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
°5ufromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
°5uisJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
°5u</pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5uCalls <a>error</a> when the key is not a <a>member</a> of the map.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5ufindIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
°5ufindIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
°5ufindIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5u</pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5uelemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
°5uelemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
elemAt :: Int -> Map k a -> (k, a)

-- | <i>O(log n)</i>. Update the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uupdateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
°5uupdateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
°5uupdateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5uupdateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5uupdateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5udeleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udeleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
°5udeleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
°5u</pre>
deleteAt :: Int -> Map k a -> Map k a

-- | Take a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Map k a -> Map k a

-- | Drop a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Split a map at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The minimal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
°5ufindMin empty = Nothing
°5u</pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The maximal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
°5ulookupMax empty = Nothing
°5u</pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The minimal key of the map. Calls <a>error</a> if the
°5umap is empty.
°5u
°5u<pre>
°5ufindMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5ufindMin empty                            Error: empty map has no minimal element
°5u</pre>
findMin :: Map k a -> (k, a)
findMax :: Map k a -> (k, a)

-- | <i>O(log n)</i>. Delete the minimal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
°5udeleteMin empty == empty
°5u</pre>
deleteMin :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the maximal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
°5udeleteMax empty == empty
°5u</pre>
deleteMax :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
°5udeleteFindMin                                            Error: can not return the minimal element of an empty map
°5u</pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
°5udeleteFindMax empty                                      Error: can not return the maximal element of an empty map
°5u</pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Retrieves the value associated with minimal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5uminView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
°5uminView empty == Nothing
°5u</pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the value associated with maximal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5umaxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
°5umaxView empty == Nothing
°5u</pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(log n)</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)
data AreWeStrict
Strict :: AreWeStrict
Lazy :: AreWeStrict
atKeyImpl :: (Functor f, Ord k) => AreWeStrict -> k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
atKeyPlain :: Ord k => AreWeStrict -> k -> (Maybe a -> Maybe a) -> Map k a -> Map k a
bin :: k -> a -> Map k a -> Map k a -> Map k a
balance :: k -> a -> Map k a -> Map k a -> Map k a
balanceL :: k -> a -> Map k a -> Map k a -> Map k a
balanceR :: k -> a -> Map k a -> Map k a -> Map k a
delta :: Int
insertMax :: k -> a -> Map k a -> Map k a
link :: k -> a -> Map k a -> Map k a -> Map k a
link2 :: Map k a -> Map k a -> Map k a
glue :: Map k a -> Map k a -> Map k a
data MaybeS a
NothingS :: MaybeS a
JustS :: !a -> MaybeS a

-- | Identity functor and monad. (a non-strict monad)
newtype Identity a
Identity :: a -> Identity a
[runIdentity] :: Identity a -> a

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: (Applicative f, Monad f) => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f k _ x</tt>.
lmapWhenMissing :: (b -> a) -> WhenMissing f k a x -> WhenMissing f k b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k _ y z</tt>.
contramapFirstWhenMatched :: (b -> a) -> WhenMatched f k a y z -> WhenMatched f k b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k x _ z</tt>.
contramapSecondWhenMatched :: (b -> a) -> WhenMatched f k x a z -> WhenMatched f k x b z

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>, using only a
°5u'Functor f' constraint.
mapGentlyWhenMissing :: Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x</tt>, using only a
°5u'Functor f' constraint.
mapGentlyWhenMatched :: Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b
instance GHC.Base.Functor f => GHC.Base.Functor (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => Control.Category.Category (Data.Map.Internal.WhenMatched f k x)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Applicative (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Monad (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Functor (Data.Map.Internal.WhenMissing f k x)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => Control.Category.Category (Data.Map.Internal.WhenMissing f k)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Applicative (Data.Map.Internal.WhenMissing f k x)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Monad (Data.Map.Internal.WhenMissing f k x)
instance GHC.Classes.Ord k => GHC.Base.Monoid (Data.Map.Internal.Map k v)
instance GHC.Classes.Ord k => GHC.Base.Semigroup (Data.Map.Internal.Map k v)
instance (Data.Data.Data k, Data.Data.Data a, GHC.Classes.Ord k) => Data.Data.Data (Data.Map.Internal.Map k a)
instance GHC.Classes.Ord k => GHC.Exts.IsList (Data.Map.Internal.Map k v)
instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Map.Internal.Map k a)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.Map.Internal.Map k v)
instance Data.Functor.Classes.Eq2 Data.Map.Internal.Map
instance GHC.Classes.Eq k => Data.Functor.Classes.Eq1 (Data.Map.Internal.Map k)
instance Data.Functor.Classes.Ord2 Data.Map.Internal.Map
instance GHC.Classes.Ord k => Data.Functor.Classes.Ord1 (Data.Map.Internal.Map k)
instance Data.Functor.Classes.Show2 Data.Map.Internal.Map
instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Map.Internal.Map k)
instance (GHC.Classes.Ord k, GHC.Read.Read k) => Data.Functor.Classes.Read1 (Data.Map.Internal.Map k)
instance GHC.Base.Functor (Data.Map.Internal.Map k)
instance Data.Traversable.Traversable (Data.Map.Internal.Map k)
instance Data.Foldable.Foldable (Data.Map.Internal.Map k)
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Map.Internal.Map k a)
instance (GHC.Classes.Ord k, GHC.Read.Read k, GHC.Read.Read e) => GHC.Read.Read (Data.Map.Internal.Map k e)
instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.Map.Internal.Map k a)


-- | This module defines an API for writing functions that merge two maps.
°5uThe key functions are <a>merge</a> and <a>mergeA</a>. Each of these
°5ucan be used with several different "merge tactics".
°5u
°5uThe <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
°5uand strict modules. Only the choice of merge tactics determines
°5ustrictness. If you use <a>mapMissing</a> from
°5u<a>Data.Map.Merge.Strict</a> then the results will be forced before
°5uthey are inserted. If you use <a>mapMissing</a> from this module then
°5uthey will not.
°5u
°5u<h2>Efficiency note</h2>
°5u
°5uThe <tt>Category</tt>, <a>Applicative</a>, and <a>Monad</a> instances
°5ufor <a>WhenMissing</a> tactics are included because they are valid.
°5uHowever, they are inefficient in many cases and should usually be
°5uavoided. The instances for <a>WhenMatched</a> tactics should not pose
°5uany major efficiency problems.
module Data.Map.Merge.Lazy

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; Maybe z
°5u</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt;
°5uMaybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
°5u                    -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
°5u               -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMatched :: Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMissing f k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
°5u</tt>.
data WhenMissing f k x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
°5u(Maybe z) </tt>.
data WhenMatched f k x y z

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  k x -&gt; (b -&gt; guard b *&gt; Just x) <a>$</a> f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: (Applicative f, Monad f) => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f k _ x</tt>.
lmapWhenMissing :: (b -> a) -> WhenMissing f k a x -> WhenMissing f k b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k _ y z</tt>.
contramapFirstWhenMatched :: (b -> a) -> WhenMatched f k a y z -> WhenMatched f k b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k x _ z</tt>.
contramapSecondWhenMatched :: (b -> a) -> WhenMatched f k x a z -> WhenMatched f k x b z

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

module Data.Map.Internal.Debug

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format. See <a>showTreeWith</a>.
showTree :: (Show k, Show a) => Map k a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> showelem hang
°5uwide map</tt>) shows the tree that implements the map. Elements are
°5ushown using the <tt>showElem</tt> function. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uMap&gt; let t = fromDistinctAscList [(x,()) | x &lt;- [1..5]]
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True False t
°5u(4,())
°5u+--(2,())
°5u|  +--(1,())
°5u|  +--(3,())
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True True t
°5u(4,())
°5u|
°5u+--(2,())
°5u|  |
°5u|  +--(1,())
°5u|  |
°5u|  +--(3,())
°5u|
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) False True t
°5u+--(5,())
°5u|
°5u(4,())
°5u|
°5u|  +--(3,())
°5u|  |
°5u+--(2,())
°5u   |
°5u   +--(1,())
°5u</pre>
showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String
showsTree :: (k -> a -> String) -> Bool -> [String] -> [String] -> Map k a -> ShowS
showsTreeHang :: (k -> a -> String) -> Bool -> [String] -> Map k a -> ShowS
showWide :: Bool -> [String] -> String -> String
showsBars :: [String] -> ShowS
node :: String
withBar :: [String] -> [String]
withEmpty :: [String] -> [String]

-- | <i>O(n)</i>. Test if the internal map structure is valid.
°5u
°5u<pre>
°5uvalid (fromAscList [(3,"b"), (5,"a")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b")]) == False
°5u</pre>
valid :: Ord k => Map k a -> Bool

-- | Test if the keys are ordered correctly.
ordered :: Ord a => Map a b -> Bool

-- | Test if a map obeys the balance invariants.
balanced :: Map k a -> Bool

-- | Test if each node of a map reports its size correctly.
validsize :: Map a b -> Bool


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uAn efficient implementation of ordered maps from keys to values
°5u(dictionaries).
°5u
°5uAPI of this module is strict in both the keys and the values. If you
°5uneed value-lazy maps, use <a>Data.Map.Lazy</a> instead. The <a>Map</a>
°5utype is shared between the lazy and strict modules, meaning that the
°5usame <a>Map</a> value can be passed to functions in both modules
°5u(although that is rarely needed).
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport qualified Data.Map.Strict as Map
°5u</pre>
°5u
°5uThe implementation of <a>Map</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
°5u
°5uNote that the implementation is <i>left-biased</i> -- the elements of
°5ua first argument are always preferred to the second, for example in
°5u<a>union</a> or <a>insert</a>.
°5u
°5u<i>Warning</i>: The size of the map must not exceed
°5u<tt>maxBound::Int</tt>. Violation of this condition is not detected
°5uand if the size limit is exceeded, its behaviour is undefined.
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation (<a>http://en.wikipedia.org/wiki/Big_O_notation</a>).
°5u
°5uBe aware that the <a>Functor</a>, <a>Traversable</a> and <tt>Data</tt>
°5uinstances are the same as for the <a>Data.Map.Lazy</a> module, so if
°5uthey are used on strict maps, the resulting maps will be lazy.
module Data.Map.Strict.Internal

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a
Bin :: {-# UNPACK #-} !Size -> !k -> a -> !(Map k a) -> !(Map k a) -> Map k a
Tip :: Map k a
type Size = Int

-- | <i>O(log n)</i>. Find the value at a key. Calls <a>error</a> when the
°5uelement can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | <i>O(log n)</i>. Find the value at a key. Returns <a>Nothing</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
°5u</pre>
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.Map.null (empty)           == True
°5uData.Map.null (singleton 1 'a') == False
°5u</pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. The number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: Map k a -> Int

-- | <i>O(log n)</i>. Is the key a member of the map? See also
°5u<a>notMember</a>.
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Is the key not a member of the map? See also
°5u<a>member</a>.
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Lookup the value at a key in the map.
°5u
°5uThe function will return the corresponding value as <tt>(<a>Just</a>
°5uvalue)</tt>, or <a>Nothing</a> if the key isn't in the map.
°5u
°5uAn example of using <tt>lookup</tt>:
°5u
°5u<pre>
°5uimport Prelude hiding (lookup)
°5uimport Data.Map
°5u
°5uemployeeDept = fromList([("John","Sales"), ("Bob","IT")])
°5udeptCountry = fromList([("IT","USA"), ("Sales","France")])
°5ucountryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
°5u
°5uemployeeCurrency :: String -&gt; Maybe String
°5uemployeeCurrency name = do
°5u    dept &lt;- lookup name employeeDept
°5u    country &lt;- lookup dept deptCountry
°5u    lookup country countryCurrency
°5u
°5umain = do
°5u    putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
°5u    putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
°5u</pre>
°5u
°5uThe output of this program:
°5u
°5u<pre>
°5uJohn's currency: Just "Euro"
°5uPete's currency: Nothing
°5u</pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | <i>O(log n)</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns default value
°5u<tt>def</tt> when the key is not in the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: Map k a

-- | <i>O(1)</i>. A map with a single element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: k -> a -> Map k a

-- | <i>O(log n)</i>. Insert a new key and value in the map. If the key is
°5ualready present in the map, the associated value is replaced with the
°5usupplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
°5u<a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining new value and old
°5uvalue. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert the pair <tt>(key, f
°5unew_value old_value)</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining key, new value and
°5uold value. <tt><a>insertWithKey</a> f key value mp</tt> will insert
°5uthe pair (key, value) into <tt>mp</tt> if key does not exist in the
°5umap. If the key does exist, the function will insert the pair
°5u<tt>(key,f key new_value old_value)</tt>. Note that the key passed to
°5uf is the same key passed to <a>insertWithKey</a>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Combines insert operation with old value retrieval.
°5uThe expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a
°5upair where the first element is equal to (<tt><a>lookup</a> k
°5umap</tt>) and the second element equal to (<tt><a>insertWithKey</a> f
°5uk x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. Delete a key and its value from the map. When the key
°5uis not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update a value at a specific key with the result of
°5uthe provided function. When the key is not a member of the map, the
°5uoriginal map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Adjust a value at a specific key. When the key is not
°5ua member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>updateWithKey</a> f k
°5umap</tt>) updates the value <tt>x</tt> at <tt>k</tt> (if it is in the
°5umap). If (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted.
°5uIf it is (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the
°5unew value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
°5ufunction returns changed value, if it is updated. Returns the original
°5ukey value if the map entry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>alter</a> f k map</tt>) alters
°5uthe value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
°5ucan be used to insert, delete, or update a value in a <a>Map</a>. In
°5ushort : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
°5um)</tt>.
°5u
°5u<pre>
°5ulet f _ = Nothing
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u
°5ulet f _ = Just "c"
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
°5u</pre>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in a <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt;
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map. When used with
°5utrivial functors like <a>Identity</a> and <a>Const</a>, it is often
°5uslightly slower than more specialized combinators like <a>lookup</a>
°5uand <a>insert</a>. However, when the functor is non-trivial and key
°5ucomparison is not particularly cheap, it is the fastest way.
°5u
°5uNote on rewrite rules:
°5u
°5uThis module includes GHC rewrite rules to optimize <a>alterF</a> for
°5uthe <a>Const</a> and <a>Identity</a> functors. In general, these rules
°5uimprove performance. The sole exception is that when using
°5u<a>Identity</a>, deleting a key that is already absent takes longer
°5uthan it would without the rules. If you expect this to occur a very
°5ularge fraction of the time, you might consider using a private copy of
°5uthe <a>Identity</a> type.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression (<tt><a>union</a>
°5ut1 t2</tt>) takes the left-biased union of <tt>t1</tt> and
°5u<tt>t2</tt>. It prefers <tt>t1</tt> when duplicate keys are
°5uencountered, i.e. (<tt><a>union</a> == <a>unionWith</a>
°5u<a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: Ord k => [Map k a] -> Map k a

-- | The union of a list of maps, with a combining operation:
°5u(<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
°5u<a>empty</a></tt>).
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two maps. Return
°5uelements of the first map not existing in the second map.
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the values
°5uof these keys. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection of two maps. Return
°5udata in the first map for the keys existing in both maps.
°5u(<tt><a>intersection</a> m1 m2 == <a>intersectionWith</a> <a>const</a>
°5um1 m2</tt>).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; Maybe z
°5u</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt;
°5uMaybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
°5u                    -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
°5u               -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMatched :: Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMissing f k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
°5u</tt>.
data WhenMissing f k x y
WhenMissing :: Map k x -> f (Map k y) -> k -> x -> f (Maybe y) -> WhenMissing f k x y
[missingSubtree] :: WhenMissing f k x y -> Map k x -> f (Map k y)
[missingKey] :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
°5u(Maybe z) </tt>.
newtype WhenMatched f k x y z
WhenMatched :: k -> x -> y -> f (Maybe z) -> WhenMatched f k x y z
[matchedKey] :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: Applicative f => (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  k x -&gt; (b -&gt; guard b *&gt; Just x) <a>$</a> f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | <i>O(n+m)</i>. An unsafe universal combining function.
°5u
°5uWARNING: This function can produce corrupt maps and its results may
°5udepend on the internal structures of its inputs. Users should prefer
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>Map</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
°5u<tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (v' -&gt; v' <a>seq</a> (k,v'))
°5u<a>$</a> f k v) (<a>toList</a> m)</tt> That is, it behaves much like a
°5uregular <a>traverse</a> except that the traversing function also has
°5uaccess to the key associated with a value and the values are forced
°5ubefore they are installed in the result map.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. Traverse keys/values and collect the <a>Just</a> results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | <i>O(n)</i>. The function <a>mapAccum</a> threads an accumulating
°5uargument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <a>mapAccumWithKey</a> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> threads an accumulating
°5uargument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n*log n)</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained by
°5uapplying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>. The value at the greater of the two
°5uoriginal keys is used as the first argument to <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
°5us</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
°5ufor any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
°5u<tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The precondition is
°5unot checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5uvalid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
°5uvalid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
°5u</pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: Map k a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: Map k a -> [k]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Return all key/value pairs
°5uin the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
°5ukeysSet empty == Data.Set.empty
°5u</pre>
keysSet :: Map k a -> Set k

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.Set.empty == empty
°5u</pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: Map k a -> [(k, a)]

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs. See
°5ualso <a>fromAscList</a>. If the list contains more than one value for
°5uthe same key, the last value for the key is retained.
°5u
°5uIf the keys of the list are ordered, linear-time implementation is
°5uused, with the performance equal to <a>fromDistinctAscList</a>.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWithKey</a>.
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ a1 ++ a2
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
°5uvalid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
°5u</pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
°5ufromDescList [(5,"a"), (5,"b"), (3,"a")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b"), (3,"a")]) == False
°5u</pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Filter all values that satisfy the predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | <i>O(n)</i>. Filter all keys/values that satisfy the predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Restrict a <a>Map</a> to only
°5uthose keys found in a <a>Set</a>.
°5u
°5u<pre>
°5um `<tt>restrictKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5um `<tt>restrictKeys'</tt> s = m `<tt>intersect</tt> <a>fromSet</a> (const ()) s
°5u</pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Remove all keys in a <a>Set</a>
°5ufrom a <a>Map</a>.
°5u
°5u<pre>
°5um `<tt>withoutKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5um `<tt>withoutKeys'</tt> s = m `<tt>difference'</tt> <a>fromSet</a> (const ()) s
°5u</pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. Take while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
°5utakeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
°5u</pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Drop while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
°5udropWhileAntitone p = <a>filterWithKey</a> (k -&gt; not (p k))
°5u</pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Divide a map at the point where a predicate on the
°5ukeys stops holding. The user is responsible for ensuring that for all
°5ukeys <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j
°5u&gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first key and to fail after
°5uthe last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller
°5uthan <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>splitLookup</a> k map</tt>)
°5usplits a map just like <a>split</a> but also returns <tt><a>lookup</a>
°5uk map</tt>.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. This function is defined as
°5u(<tt><a>isSubmapOf</a> = <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression
°5u(<tt><a>isSubmapOfBy</a> f t1 t2</tt>) returns <a>True</a> if all keys
°5uin <tt>t1</tt> are in tree <tt>t2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
°5u</pre>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). Defined as (<tt><a>isProperSubmapOf</a> =
°5u<a>isProperSubmapOfBy</a> (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). The expression (<tt><a>isProperSubmapOfBy</a> f
°5um1 m2</tt>) returns <a>True</a> when <tt>m1</tt> and <tt>m2</tt> are
°5unot equal, all keys in <tt>m1</tt> are in <tt>m2</tt>, and when
°5u<tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(log n)</i>. Lookup the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5u
°5u<pre>
°5uisJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
°5ufromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
°5ufromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
°5uisJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
°5u</pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5uCalls <a>error</a> when the key is not a <a>member</a> of the map.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5ufindIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
°5ufindIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
°5ufindIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5u</pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5uelemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
°5uelemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
elemAt :: Int -> Map k a -> (k, a)

-- | <i>O(log n)</i>. Update the element at <i>index</i>. Calls
°5u<a>error</a> when an invalid index is used.
°5u
°5u<pre>
°5uupdateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
°5uupdateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
°5uupdateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5uupdateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5uupdateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5udeleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udeleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
°5udeleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
°5u</pre>
deleteAt :: Int -> Map k a -> Map k a

-- | Take a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Map k a -> Map k a

-- | Drop a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Split a map at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The minimal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
°5ufindMin empty = Nothing
°5u</pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The maximal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
°5ulookupMax empty = Nothing
°5u</pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The minimal key of the map. Calls <a>error</a> if the
°5umap is empty.
°5u
°5u<pre>
°5ufindMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5ufindMin empty                            Error: empty map has no minimal element
°5u</pre>
findMin :: Map k a -> (k, a)
findMax :: Map k a -> (k, a)

-- | <i>O(log n)</i>. Delete the minimal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
°5udeleteMin empty == empty
°5u</pre>
deleteMin :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the maximal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
°5udeleteMax empty == empty
°5u</pre>
deleteMax :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
°5udeleteFindMin                                            Error: can not return the minimal element of an empty map
°5u</pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
°5udeleteFindMax empty                                      Error: can not return the maximal element of an empty map
°5u</pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Retrieves the value associated with minimal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5uminView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
°5uminView empty == Nothing
°5u</pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the value associated with maximal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5umaxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
°5umaxView empty == Nothing
°5u</pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(log n)</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format. See <a>showTreeWith</a>.

-- | <i>Deprecated: <a>showTree</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTree :: (Show k, Show a) => Map k a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> showelem hang
°5uwide map</tt>) shows the tree that implements the map. Elements are
°5ushown using the <tt>showElem</tt> function. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uMap&gt; let t = fromDistinctAscList [(x,()) | x &lt;- [1..5]]
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True False t
°5u(4,())
°5u+--(2,())
°5u|  +--(1,())
°5u|  +--(3,())
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True True t
°5u(4,())
°5u|
°5u+--(2,())
°5u|  |
°5u|  +--(1,())
°5u|  |
°5u|  +--(3,())
°5u|
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) False True t
°5u+--(5,())
°5u|
°5u(4,())
°5u|
°5u|  +--(3,())
°5u|  |
°5u+--(2,())
°5u   |
°5u   +--(1,())
°5u</pre>

-- | <i>Deprecated: <a>showTreeWith</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String

-- | <i>O(n)</i>. Test if the internal map structure is valid.
°5u
°5u<pre>
°5uvalid (fromAscList [(3,"b"), (5,"a")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b")]) == False
°5u</pre>
valid :: Ord k => Map k a -> Bool


-- | <h1>Finite Maps (strict interface)</h1>
°5u
°5uThe <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
°5ucalled a dictionary) from keys of type <tt>k</tt> to values of type
°5u<tt>v</tt>.
°5u
°5uEach function in this module is careful to force values before
°5uinstalling them in a <a>Map</a>. This is usually more efficient when
°5ulaziness is not necessary. When laziness <i>is</i> required, use the
°5ufunctions in <a>Data.Map.Lazy</a>.
°5u
°5uIn particular, the functions in this module obey the following law:
°5u
°5u<ul>
°5u<li>If all values stored in all maps in the arguments are in WHNF,
°5uthen all values stored in all maps in the results will be in WHNF once
°5uthose maps are evaluated.</li>
°5u</ul>
°5u
°5uWhen deciding if this is the correct data structure to use, consider:
°5u
°5u<ul>
°5u<li>If you are using <tt>Int</tt> keys, you will get much better
°5uperformance for most operations using <a>Data.IntMap.Strict</a>.</li>
°5u<li>If you don't care about ordering, consider use
°5u<tt>Data.HashMap.Strict</tt> from the <a>unordered-containers</a>
°5upackage instead.</li>
°5u</ul>
°5u
°5uFor a walkthrough of the most commonly used functions see the <a>maps
°5uintroduction</a>.
°5u
°5uThis module is intended to be imported qualified, to avoid name
°5uclashes with Prelude functions:
°5u
°5u<pre>
°5uimport qualified Data.Map.Strict as Map
°5u</pre>
°5u
°5uNote that the implementation is generally <i>left-biased</i>.
°5uFunctions that take two maps as arguments and combine them, such as
°5u<a>union</a> and <a>intersection</a>, prefer the values in the first
°5uargument to those in the second.
°5u
°5u<h2>Detailed performance information</h2>
°5u
°5uThe amortized running time is given for each operation, with <i>n</i>
°5ureferring to the number of entries in the map.
°5u
°5uBenchmarks comparing <a>Data.Map.Strict</a> with other dictionary
°5uimplementations can be found at
°5u<a>https://github.com/haskell-perf/dictionaries</a>.
°5u
°5u<h2>Warning</h2>
°5u
°5uThe size of a <a>Map</a> must not exceed <tt>maxBound::Int</tt>.
°5uViolation of this condition is not detected and if the size limit is
°5uexceeded, its behaviour is undefined.
°5u
°5uThe <a>Map</a> type is shared between the lazy and strict modules,
°5umeaning that the same <a>Map</a> value can be passed to functions in
°5uboth modules. This means that the <tt>Functor</tt>,
°5u<tt>Traversable</tt> and <tt>Data</tt> instances are the same as for
°5uthe <a>Data.Map.Lazy</a> module, so if they are used on strict maps,
°5uthe resulting maps may contain suspended values (thunks).
°5u
°5u<h2>Implementation</h2>
°5u
°5uThe implementation of <a>Map</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
module Data.Map.Strict

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a

-- | <i>O(log n)</i>. Find the value at a key. Calls <a>error</a> when the
°5uelement can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | <i>O(log n)</i>. Find the value at a key. Returns <a>Nothing</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
°5u</pre>
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.Map.null (empty)           == True
°5uData.Map.null (singleton 1 'a') == False
°5u</pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. The number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: Map k a -> Int

-- | <i>O(log n)</i>. Is the key a member of the map? See also
°5u<a>notMember</a>.
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Is the key not a member of the map? See also
°5u<a>member</a>.
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Lookup the value at a key in the map.
°5u
°5uThe function will return the corresponding value as <tt>(<a>Just</a>
°5uvalue)</tt>, or <a>Nothing</a> if the key isn't in the map.
°5u
°5uAn example of using <tt>lookup</tt>:
°5u
°5u<pre>
°5uimport Prelude hiding (lookup)
°5uimport Data.Map
°5u
°5uemployeeDept = fromList([("John","Sales"), ("Bob","IT")])
°5udeptCountry = fromList([("IT","USA"), ("Sales","France")])
°5ucountryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
°5u
°5uemployeeCurrency :: String -&gt; Maybe String
°5uemployeeCurrency name = do
°5u    dept &lt;- lookup name employeeDept
°5u    country &lt;- lookup dept deptCountry
°5u    lookup country countryCurrency
°5u
°5umain = do
°5u    putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
°5u    putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
°5u</pre>
°5u
°5uThe output of this program:
°5u
°5u<pre>
°5uJohn's currency: Just "Euro"
°5uPete's currency: Nothing
°5u</pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | <i>O(log n)</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns default value
°5u<tt>def</tt> when the key is not in the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: Map k a

-- | <i>O(1)</i>. A map with a single element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: k -> a -> Map k a

-- | <i>O(log n)</i>. Insert a new key and value in the map. If the key is
°5ualready present in the map, the associated value is replaced with the
°5usupplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
°5u<a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining new value and old
°5uvalue. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert the pair <tt>(key, f
°5unew_value old_value)</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining key, new value and
°5uold value. <tt><a>insertWithKey</a> f key value mp</tt> will insert
°5uthe pair (key, value) into <tt>mp</tt> if key does not exist in the
°5umap. If the key does exist, the function will insert the pair
°5u<tt>(key,f key new_value old_value)</tt>. Note that the key passed to
°5uf is the same key passed to <a>insertWithKey</a>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Combines insert operation with old value retrieval.
°5uThe expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a
°5upair where the first element is equal to (<tt><a>lookup</a> k
°5umap</tt>) and the second element equal to (<tt><a>insertWithKey</a> f
°5uk x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. Delete a key and its value from the map. When the key
°5uis not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update a value at a specific key with the result of
°5uthe provided function. When the key is not a member of the map, the
°5uoriginal map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Adjust a value at a specific key. When the key is not
°5ua member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>updateWithKey</a> f k
°5umap</tt>) updates the value <tt>x</tt> at <tt>k</tt> (if it is in the
°5umap). If (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted.
°5uIf it is (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the
°5unew value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
°5ufunction returns changed value, if it is updated. Returns the original
°5ukey value if the map entry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>alter</a> f k map</tt>) alters
°5uthe value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
°5ucan be used to insert, delete, or update a value in a <a>Map</a>. In
°5ushort : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
°5um)</tt>.
°5u
°5u<pre>
°5ulet f _ = Nothing
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u
°5ulet f _ = Just "c"
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
°5u</pre>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in a <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt;
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map. When used with
°5utrivial functors like <a>Identity</a> and <a>Const</a>, it is often
°5uslightly slower than more specialized combinators like <a>lookup</a>
°5uand <a>insert</a>. However, when the functor is non-trivial and key
°5ucomparison is not particularly cheap, it is the fastest way.
°5u
°5uNote on rewrite rules:
°5u
°5uThis module includes GHC rewrite rules to optimize <a>alterF</a> for
°5uthe <a>Const</a> and <a>Identity</a> functors. In general, these rules
°5uimprove performance. The sole exception is that when using
°5u<a>Identity</a>, deleting a key that is already absent takes longer
°5uthan it would without the rules. If you expect this to occur a very
°5ularge fraction of the time, you might consider using a private copy of
°5uthe <a>Identity</a> type.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression (<tt><a>union</a>
°5ut1 t2</tt>) takes the left-biased union of <tt>t1</tt> and
°5u<tt>t2</tt>. It prefers <tt>t1</tt> when duplicate keys are
°5uencountered, i.e. (<tt><a>union</a> == <a>unionWith</a>
°5u<a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: Ord k => [Map k a] -> Map k a

-- | The union of a list of maps, with a combining operation:
°5u(<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
°5u<a>empty</a></tt>).
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two maps. Return
°5uelements of the first map not existing in the second map.
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the values
°5uof these keys. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection of two maps. Return
°5udata in the first map for the keys existing in both maps.
°5u(<tt><a>intersection</a> m1 m2 == <a>intersectionWith</a> <a>const</a>
°5um1 m2</tt>).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n+m)</i>. An unsafe universal combining function.
°5u
°5uWARNING: This function can produce corrupt maps and its results may
°5udepend on the internal structures of its inputs. Users should prefer
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>Map</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
°5u<tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (v' -&gt; v' <a>seq</a> (k,v'))
°5u<a>$</a> f k v) (<a>toList</a> m)</tt> That is, it behaves much like a
°5uregular <a>traverse</a> except that the traversing function also has
°5uaccess to the key associated with a value and the values are forced
°5ubefore they are installed in the result map.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. Traverse keys/values and collect the <a>Just</a> results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | <i>O(n)</i>. The function <a>mapAccum</a> threads an accumulating
°5uargument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <a>mapAccumWithKey</a> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> threads an accumulating
°5uargument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n*log n)</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained by
°5uapplying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>. The value at the greater of the two
°5uoriginal keys is used as the first argument to <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
°5us</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
°5ufor any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
°5u<tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The precondition is
°5unot checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5uvalid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
°5uvalid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
°5u</pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: Map k a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: Map k a -> [k]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Return all key/value pairs
°5uin the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
°5ukeysSet empty == Data.Set.empty
°5u</pre>
keysSet :: Map k a -> Set k

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.Set.empty == empty
°5u</pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: Map k a -> [(k, a)]

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs. See
°5ualso <a>fromAscList</a>. If the list contains more than one value for
°5uthe same key, the last value for the key is retained.
°5u
°5uIf the keys of the list are ordered, linear-time implementation is
°5uused, with the performance equal to <a>fromDistinctAscList</a>.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWithKey</a>.
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ a1 ++ a2
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
°5uvalid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
°5u</pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
°5ufromDescList [(5,"a"), (5,"b"), (3,"a")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b"), (3,"a")]) == False
°5u</pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Filter all values that satisfy the predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | <i>O(n)</i>. Filter all keys/values that satisfy the predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Restrict a <a>Map</a> to only
°5uthose keys found in a <a>Set</a>.
°5u
°5u<pre>
°5um `<tt>restrictKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5um `<tt>restrictKeys'</tt> s = m `<tt>intersect</tt> <a>fromSet</a> (const ()) s
°5u</pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Remove all keys in a <a>Set</a>
°5ufrom a <a>Map</a>.
°5u
°5u<pre>
°5um `<tt>withoutKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5um `<tt>withoutKeys'</tt> s = m `<tt>difference'</tt> <a>fromSet</a> (const ()) s
°5u</pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. Take while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
°5utakeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
°5u</pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Drop while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
°5udropWhileAntitone p = <a>filterWithKey</a> (k -&gt; not (p k))
°5u</pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Divide a map at the point where a predicate on the
°5ukeys stops holding. The user is responsible for ensuring that for all
°5ukeys <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j
°5u&gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first key and to fail after
°5uthe last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller
°5uthan <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>splitLookup</a> k map</tt>)
°5usplits a map just like <a>split</a> but also returns <tt><a>lookup</a>
°5uk map</tt>.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. This function is defined as
°5u(<tt><a>isSubmapOf</a> = <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression
°5u(<tt><a>isSubmapOfBy</a> f t1 t2</tt>) returns <a>True</a> if all keys
°5uin <tt>t1</tt> are in tree <tt>t2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
°5u</pre>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). Defined as (<tt><a>isProperSubmapOf</a> =
°5u<a>isProperSubmapOfBy</a> (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). The expression (<tt><a>isProperSubmapOfBy</a> f
°5um1 m2</tt>) returns <a>True</a> when <tt>m1</tt> and <tt>m2</tt> are
°5unot equal, all keys in <tt>m1</tt> are in <tt>m2</tt>, and when
°5u<tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(log n)</i>. Lookup the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5u
°5u<pre>
°5uisJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
°5ufromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
°5ufromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
°5uisJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
°5u</pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5uCalls <a>error</a> when the key is not a <a>member</a> of the map.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5ufindIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
°5ufindIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
°5ufindIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5u</pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5uelemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
°5uelemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
elemAt :: Int -> Map k a -> (k, a)

-- | <i>O(log n)</i>. Update the element at <i>index</i>. Calls
°5u<a>error</a> when an invalid index is used.
°5u
°5u<pre>
°5uupdateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
°5uupdateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
°5uupdateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5uupdateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5uupdateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5udeleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udeleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
°5udeleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
°5u</pre>
deleteAt :: Int -> Map k a -> Map k a

-- | Take a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Map k a -> Map k a

-- | Drop a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Split a map at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The minimal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
°5ufindMin empty = Nothing
°5u</pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The maximal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
°5ulookupMax empty = Nothing
°5u</pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The minimal key of the map. Calls <a>error</a> if the
°5umap is empty.
°5u
°5u<pre>
°5ufindMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5ufindMin empty                            Error: empty map has no minimal element
°5u</pre>
findMin :: Map k a -> (k, a)
findMax :: Map k a -> (k, a)

-- | <i>O(log n)</i>. Delete the minimal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
°5udeleteMin empty == empty
°5u</pre>
deleteMin :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the maximal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
°5udeleteMax empty == empty
°5u</pre>
deleteMax :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
°5udeleteFindMin                                            Error: can not return the minimal element of an empty map
°5u</pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
°5udeleteFindMax empty                                      Error: can not return the maximal element of an empty map
°5u</pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Retrieves the value associated with minimal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5uminView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
°5uminView empty == Nothing
°5u</pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the value associated with maximal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5umaxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
°5umaxView empty == Nothing
°5u</pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(log n)</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format. See <a>showTreeWith</a>.

-- | <i>Deprecated: <a>showTree</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTree :: (Show k, Show a) => Map k a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> showelem hang
°5uwide map</tt>) shows the tree that implements the map. Elements are
°5ushown using the <tt>showElem</tt> function. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uMap&gt; let t = fromDistinctAscList [(x,()) | x &lt;- [1..5]]
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True False t
°5u(4,())
°5u+--(2,())
°5u|  +--(1,())
°5u|  +--(3,())
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True True t
°5u(4,())
°5u|
°5u+--(2,())
°5u|  |
°5u|  +--(1,())
°5u|  |
°5u|  +--(3,())
°5u|
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) False True t
°5u+--(5,())
°5u|
°5u(4,())
°5u|
°5u|  +--(3,())
°5u|  |
°5u+--(2,())
°5u   |
°5u   +--(1,())
°5u</pre>

-- | <i>Deprecated: <a>showTreeWith</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String

-- | <i>O(n)</i>. Test if the internal map structure is valid.
°5u
°5u<pre>
°5uvalid (fromAscList [(3,"b"), (5,"a")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b")]) == False
°5u</pre>
valid :: Ord k => Map k a -> Bool


-- | This module defines an API for writing functions that merge two maps.
°5uThe key functions are <a>merge</a> and <a>mergeA</a>. Each of these
°5ucan be used with several different "merge tactics".
°5u
°5uThe <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
°5uand strict modules. Only the choice of merge tactics determines
°5ustrictness. If you use <a>mapMissing</a> from this module then the
°5uresults will be forced before they are inserted. If you use
°5u<a>mapMissing</a> from <a>Data.Map.Merge.Lazy</a> then they will not.
°5u
°5u<h2>Efficiency note</h2>
°5u
°5uThe <tt>Category</tt>, <a>Applicative</a>, and <a>Monad</a> instances
°5ufor <a>WhenMissing</a> tactics are included because they are valid.
°5uHowever, they are inefficient in many cases and should usually be
°5uavoided. The instances for <a>WhenMatched</a> tactics should not pose
°5uany major efficiency problems.
module Data.Map.Merge.Strict

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; Maybe z
°5u</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt;
°5uMaybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
°5u                    -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
°5u               -&gt; SimpleWhenMatched k x y z
°5u</pre>
zipWithMatched :: Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMissing f k x z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
°5u</tt>.
data WhenMissing f k x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
°5urepresentation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
°5u(Maybe z) </tt>.
data WhenMatched f k x y z

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: Applicative f => (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  k x -&gt; (b -&gt; guard b *&gt; Just x) <a>$</a> f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)


-- | <h1>Finite Maps (lazy interface)</h1>
°5u
°5uThe <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
°5ucalled a dictionary) from keys of type <tt>k</tt> to values of type
°5u<tt>v</tt>. A <a>Map</a> is strict in its keys but lazy in its values.
°5u
°5uThe functions in <a>Data.Map.Strict</a> are careful to force values
°5ubefore installing them in a <a>Map</a>. This is usually more efficient
°5uin cases where laziness is not essential. The functions in this module
°5udo not do so.
°5u
°5uWhen deciding if this is the correct data structure to use, consider:
°5u
°5u<ul>
°5u<li>If you are using <tt>Int</tt> keys, you will get much better
°5uperformance for most operations using <a>Data.IntMap.Lazy</a>.</li>
°5u<li>If you don't care about ordering, consider using
°5u<tt>Data.HashMap.Lazy</tt> from the <a>unordered-containers</a>
°5upackage instead.</li>
°5u</ul>
°5u
°5uFor a walkthrough of the most commonly used functions see the <a>maps
°5uintroduction</a>.
°5u
°5uThis module is intended to be imported qualified, to avoid name
°5uclashes with Prelude functions:
°5u
°5u<pre>
°5uimport qualified Data.Map.Lazy as Map
°5u</pre>
°5u
°5uNote that the implementation is generally <i>left-biased</i>.
°5uFunctions that take two maps as arguments and combine them, such as
°5u<a>union</a> and <a>intersection</a>, prefer the values in the first
°5uargument to those in the second.
°5u
°5u<h2>Detailed performance information</h2>
°5u
°5uThe amortized running time is given for each operation, with <i>n</i>
°5ureferring to the number of entries in the map.
°5u
°5uBenchmarks comparing <a>Data.Map.Lazy</a> with other dictionary
°5uimplementations can be found at
°5u<a>https://github.com/haskell-perf/dictionaries</a>.
°5u
°5u<h2>Warning</h2>
°5u
°5uThe size of a <a>Map</a> must not exceed <tt>maxBound::Int</tt>.
°5uViolation of this condition is not detected and if the size limit is
°5uexceeded, its behaviour is undefined.
°5u
°5u<h2>Implementation</h2>
°5u
°5uThe implementation of <a>Map</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
module Data.Map.Lazy

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a

-- | <i>O(log n)</i>. Find the value at a key. Calls <a>error</a> when the
°5uelement can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | <i>O(log n)</i>. Find the value at a key. Returns <a>Nothing</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
°5u</pre>
°5u
°5u<pre>
°5ufromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.Map.null (empty)           == True
°5uData.Map.null (singleton 1 'a') == False
°5u</pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. The number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: Map k a -> Int

-- | <i>O(log n)</i>. Is the key a member of the map? See also
°5u<a>notMember</a>.
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Is the key not a member of the map? See also
°5u<a>member</a>.
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | <i>O(log n)</i>. Lookup the value at a key in the map.
°5u
°5uThe function will return the corresponding value as <tt>(<a>Just</a>
°5uvalue)</tt>, or <a>Nothing</a> if the key isn't in the map.
°5u
°5uAn example of using <tt>lookup</tt>:
°5u
°5u<pre>
°5uimport Prelude hiding (lookup)
°5uimport Data.Map
°5u
°5uemployeeDept = fromList([("John","Sales"), ("Bob","IT")])
°5udeptCountry = fromList([("IT","USA"), ("Sales","France")])
°5ucountryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
°5u
°5uemployeeCurrency :: String -&gt; Maybe String
°5uemployeeCurrency name = do
°5u    dept &lt;- lookup name employeeDept
°5u    country &lt;- lookup dept deptCountry
°5u    lookup country countryCurrency
°5u
°5umain = do
°5u    putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
°5u    putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
°5u</pre>
°5u
°5uThe output of this program:
°5u
°5u<pre>
°5uJohn's currency: Just "Euro"
°5uPete's currency: Nothing
°5u</pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | <i>O(log n)</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns default value
°5u<tt>def</tt> when the key is not in the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: Map k a

-- | <i>O(1)</i>. A map with a single element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: k -> a -> Map k a

-- | <i>O(log n)</i>. Insert a new key and value in the map. If the key is
°5ualready present in the map, the associated value is replaced with the
°5usupplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
°5u<a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining new value and old
°5uvalue. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert the pair <tt>(key, f
°5unew_value old_value)</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Insert with a function, combining key, new value and
°5uold value. <tt><a>insertWithKey</a> f key value mp</tt> will insert
°5uthe pair (key, value) into <tt>mp</tt> if key does not exist in the
°5umap. If the key does exist, the function will insert the pair
°5u<tt>(key,f key new_value old_value)</tt>. Note that the key passed to
°5uf is the same key passed to <a>insertWithKey</a>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Combines insert operation with old value retrieval.
°5uThe expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a
°5upair where the first element is equal to (<tt><a>lookup</a> k
°5umap</tt>) and the second element equal to (<tt><a>insertWithKey</a> f
°5uk x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. Delete a key and its value from the map. When the key
°5uis not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update a value at a specific key with the result of
°5uthe provided function. When the key is not a member of the map, the
°5uoriginal map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Adjust a value at a specific key. When the key is not
°5ua member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>updateWithKey</a> f k
°5umap</tt>) updates the value <tt>x</tt> at <tt>k</tt> (if it is in the
°5umap). If (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted.
°5uIf it is (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the
°5unew value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
°5ufunction returns changed value, if it is updated. Returns the original
°5ukey value if the map entry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>alter</a> f k map</tt>) alters
°5uthe value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
°5ucan be used to insert, delete, or update a value in a <a>Map</a>. In
°5ushort : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
°5um)</tt>.
°5u
°5u<pre>
°5ulet f _ = Nothing
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u
°5ulet f _ = Just "c"
°5ualter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
°5ualter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
°5u</pre>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in a <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt;
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map. When used with
°5utrivial functors like <a>Identity</a> and <a>Const</a>, it is often
°5uslightly slower than more specialized combinators like <a>lookup</a>
°5uand <a>insert</a>. However, when the functor is non-trivial and key
°5ucomparison is not particularly cheap, it is the fastest way.
°5u
°5uNote on rewrite rules:
°5u
°5uThis module includes GHC rewrite rules to optimize <a>alterF</a> for
°5uthe <a>Const</a> and <a>Identity</a> functors. In general, these rules
°5uimprove performance. The sole exception is that when using
°5u<a>Identity</a>, deleting a key that is already absent takes longer
°5uthan it would without the rules. If you expect this to occur a very
°5ularge fraction of the time, you might consider using a private copy of
°5uthe <a>Identity</a> type.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression (<tt><a>union</a>
°5ut1 t2</tt>) takes the left-biased union of <tt>t1</tt> and
°5u<tt>t2</tt>. It prefers <tt>t1</tt> when duplicate keys are
°5uencountered, i.e. (<tt><a>union</a> == <a>unionWith</a>
°5u<a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
°5u<a>union</a> <a>empty</a></tt>).
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: Ord k => [Map k a] -> Map k a

-- | The union of a list of maps, with a combining operation:
°5u(<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
°5u<a>empty</a></tt>).
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Difference of two maps. Return
°5uelements of the first map not existing in the second map.
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the values
°5uof these keys. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection of two maps. Return
°5udata in the first map for the keys existing in both maps.
°5u(<tt><a>intersection</a> m1 m2 == <a>intersectionWith</a> <a>const</a>
°5um1 m2</tt>).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Intersection with a combining
°5ufunction.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n+m)</i>. An unsafe general combining function.
°5u
°5uWARNING: This function can produce corrupt maps and its results may
°5udepend on the internal structures of its inputs. Users should prefer
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>Map</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt>,
°5u<tt><a>filterWithKey</a> f</tt>, or <tt><a>mapMaybeWithKey</a> f</tt>
°5ucould be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
°5u(<a>toList</a> m)</tt> That is, behaves exactly like a regular
°5u<a>traverse</a> except that the traversing function also has access to
°5uthe key associated with a value.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. Traverse keys/values and collect the <a>Just</a> results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | <i>O(n)</i>. The function <a>mapAccum</a> threads an accumulating
°5uargument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <a>mapAccumWithKey</a> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> threads an accumulating
°5uargument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | <i>O(n*log n)</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained by
°5uapplying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>. The value at the greater of the two
°5uoriginal keys is used as the first argument to <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
°5us</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
°5ufor any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
°5u<tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The precondition is
°5unot checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5uvalid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
°5uvalid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
°5u</pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: Map k a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: Map k a -> [k]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Return all key/value pairs
°5uin the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
°5ukeysSet empty == Data.Set.empty
°5u</pre>
keysSet :: Map k a -> Set k

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.Set.empty == empty
°5u</pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: Map k a -> [(k, a)]

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs. See
°5ualso <a>fromAscList</a>. If the list contains more than one value for
°5uthe same key, the last value for the key is retained.
°5u
°5uIf the keys of the list are ordered, linear-time implementation is
°5uused, with the performance equal to <a>fromDistinctAscList</a>.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
°5ucombining function. See also <a>fromAscListWithKey</a>.
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ a1 ++ a2
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: Map k a -> [(k, a)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
°5uvalid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5uascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
°5uvalid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
°5uvalid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
°5u</pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time. <i>The
°5uprecondition (input list is descending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
°5ufromDescList [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "b")]
°5uvalid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ufromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
°5uvalid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list in linear time with a
°5ucombining function for equal keys. <i>The precondition (input list is
°5udescending) is not checked.</i>
°5u
°5u<pre>
°5ulet f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
°5ufromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
°5uvalid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
°5uvalid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
°5u</pre>
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from a descending list of distinct elements
°5uin linear time. <i>The precondition is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
°5uvalid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
°5uvalid (fromDistinctDescList [(5,"a"), (5,"b"), (3,"b")]) == False
°5u</pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | <i>O(n)</i>. Filter all values that satisfy the predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | <i>O(n)</i>. Filter all keys/values that satisfy the predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Restrict a <a>Map</a> to only
°5uthose keys found in a <a>Set</a>.
°5u
°5u<pre>
°5um `<tt>restrictKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5um `<tt>restrictKeys'</tt> s = m `<tt>intersect</tt> <a>fromSet</a> (const ()) s
°5u</pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Remove all keys in a <a>Set</a>
°5ufrom a <a>Map</a>.
°5u
°5u<pre>
°5um `<tt>withoutKeys'</tt> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5um `<tt>withoutKeys'</tt> s = m `<tt>difference'</tt> <a>fromSet</a> (const ()) s
°5u</pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Partition the map according to a predicate. The first map
°5ucontains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. Take while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5utakeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
°5utakeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
°5u</pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Drop while a predicate on the keys holds. The user is
°5uresponsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
°5uin the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
°5u<a>spanAntitone</a>.
°5u
°5u<pre>
°5udropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
°5udropWhileAntitone p = <a>filterWithKey</a> (k -&gt; not (p k))
°5u</pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Divide a map at the point where a predicate on the
°5ukeys stops holding. The user is responsible for ensuring that for all
°5ukeys <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j
°5u&gt;= p k</tt>.
°5u
°5u<pre>
°5uspanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
°5uspanAntitone p xs = partition p xs
°5u</pre>
°5u
°5uNote: if <tt>p</tt> is not actually antitone, then
°5u<tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
°5upoint where the predicate switches from holding to not holding (where
°5uthe predicate is seen to hold before the first key and to fail after
°5uthe last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | <i>O(log n)</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller
°5uthan <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The expression (<tt><a>splitLookup</a> k map</tt>)
°5usplits a map just like <a>split</a> but also returns <tt><a>lookup</a>
°5uk map</tt>.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than three
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. This function is defined as
°5u(<tt><a>isSubmapOf</a> = <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. The expression
°5u(<tt><a>isSubmapOfBy</a> f t1 t2</tt>) returns <a>True</a> if all keys
°5uin <tt>t1</tt> are in tree <tt>t2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
°5uisSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
°5u</pre>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). Defined as (<tt><a>isProperSubmapOf</a> =
°5u<a>isProperSubmapOfBy</a> (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | <i>O(m*log(n/m + 1)), m &lt;= n</i>. Is this a proper submap? (ie. a
°5usubmap but not equal). The expression (<tt><a>isProperSubmapOfBy</a> f
°5um1 m2</tt>) returns <a>True</a> when <tt>m1</tt> and <tt>m2</tt> are
°5unot equal, all keys in <tt>m1</tt> are in <tt>m2</tt>, and when
°5u<tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(log n)</i>. Lookup the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5u
°5u<pre>
°5uisJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
°5ufromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
°5ufromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
°5uisJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
°5u</pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | <i>O(log n)</i>. Return the <i>index</i> of a key, which is its
°5uzero-based index in the sequence sorted by keys. The index is a number
°5ufrom <i>0</i> up to, but not including, the <a>size</a> of the map.
°5uCalls <a>error</a> when the key is not a <a>member</a> of the map.
°5u
°5u<pre>
°5ufindIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5ufindIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
°5ufindIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
°5ufindIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
°5u</pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | <i>O(log n)</i>. Retrieve an element by its <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uelemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5uelemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
°5uelemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
elemAt :: Int -> Map k a -> (k, a)

-- | <i>O(log n)</i>. Update the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5uupdateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
°5uupdateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
°5uupdateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5uupdateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5uupdateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5uupdateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
°5u</pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the element at <i>index</i>, i.e. by its
°5uzero-based index in the sequence sorted by keys. If the <i>index</i>
°5uis out of range (less than zero, greater or equal to <a>size</a> of
°5uthe map), <a>error</a> is called.
°5u
°5u<pre>
°5udeleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5udeleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udeleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
°5udeleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
°5u</pre>
deleteAt :: Int -> Map k a -> Map k a

-- | Take a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5utake n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
°5u</pre>
take :: Int -> Map k a -> Map k a

-- | Drop a given number of entries in key order, beginning with the
°5usmallest keys.
°5u
°5u<pre>
°5udrop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
°5u</pre>
drop :: Int -> Map k a -> Map k a

-- | <i>O(log n)</i>. Split a map at a particular index.
°5u
°5u<pre>
°5usplitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
°5u</pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | <i>O(log n)</i>. The minimal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
°5ufindMin empty = Nothing
°5u</pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The maximal key of the map. Returns <a>Nothing</a> if
°5uthe map is empty.
°5u
°5u<pre>
°5ulookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
°5ulookupMax empty = Nothing
°5u</pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | <i>O(log n)</i>. The minimal key of the map. Calls <a>error</a> if the
°5umap is empty.
°5u
°5u<pre>
°5ufindMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
°5ufindMin empty                            Error: empty map has no minimal element
°5u</pre>
findMin :: Map k a -> (k, a)
findMax :: Map k a -> (k, a)

-- | <i>O(log n)</i>. Delete the minimal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
°5udeleteMin empty == empty
°5u</pre>
deleteMin :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete the maximal key. Returns an empty map if the
°5umap is empty.
°5u
°5u<pre>
°5udeleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
°5udeleteMax empty == empty
°5u</pre>
deleteMax :: Map k a -> Map k a

-- | <i>O(log n)</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
°5udeleteFindMin                                            Error: can not return the minimal element of an empty map
°5u</pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
°5udeleteFindMax empty                                      Error: can not return the maximal element of an empty map
°5u</pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | <i>O(log n)</i>. Retrieves the value associated with minimal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5uminView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
°5uminView empty == Nothing
°5u</pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the value associated with maximal key of
°5uthe map, and the map stripped of that element, or <a>Nothing</a> if
°5upassed an empty map.
°5u
°5u<pre>
°5umaxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
°5umaxView empty == Nothing
°5u</pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | <i>O(log n)</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(log n)</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format. See <a>showTreeWith</a>.

-- | <i>Deprecated: <a>showTree</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTree :: (Show k, Show a) => Map k a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> showelem hang
°5uwide map</tt>) shows the tree that implements the map. Elements are
°5ushown using the <tt>showElem</tt> function. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
°5u
°5u<pre>
°5uMap&gt; let t = fromDistinctAscList [(x,()) | x &lt;- [1..5]]
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True False t
°5u(4,())
°5u+--(2,())
°5u|  +--(1,())
°5u|  +--(3,())
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True True t
°5u(4,())
°5u|
°5u+--(2,())
°5u|  |
°5u|  +--(1,())
°5u|  |
°5u|  +--(3,())
°5u|
°5u+--(5,())
°5u
°5uMap&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) False True t
°5u+--(5,())
°5u|
°5u(4,())
°5u|
°5u|  +--(3,())
°5u|  |
°5u+--(2,())
°5u   |
°5u   +--(1,())
°5u</pre>

-- | <i>Deprecated: <a>showTreeWith</a> is now in
°5u<a>Data.Map.Internal.Debug</a></i>
showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String

-- | <i>O(n)</i>. Test if the internal map structure is valid.
°5u
°5u<pre>
°5uvalid (fromAscList [(3,"b"), (5,"a")]) == True
°5uvalid (fromAscList [(5,"a"), (3,"b")]) == False
°5u</pre>
valid :: Ord k => Map k a -> Bool


-- | <i>Note:</i> You should use <a>Data.Map.Strict</a> instead of this
°5umodule if:
°5u
°5u<ul>
°5u<li>You will eventually need all the values stored.</li>
°5u<li>The stored values don't represent large virtual data structures to
°5ube lazily computed.</li>
°5u</ul>
°5u
°5uAn efficient implementation of ordered maps from keys to values
°5u(dictionaries).
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport qualified Data.Map as Map
°5u</pre>
°5u
°5uThe implementation of <a>Map</a> is based on <i>size balanced</i>
°5ubinary trees (or trees of <i>bounded balance</i>) as described by:
°5u
°5u<ul>
°5u<li>Stephen Adams, "<i>Efficient sets: a balancing act</i>", Journal
°5uof Functional Programming 3(4):553-562, October 1993,
°5u<a>http://www.swiss.ai.mit.edu/~adams/BB/</a>.</li>
°5u<li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
°5ubounded balance</i>", SIAM journal of computing 2(1), March 1973.</li>
°5u</ul>
°5u
°5uBounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
°5uare as given by
°5u
°5u<ul>
°5u<li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Just Join for
°5uParallel Ordered Sets</i>",
°5u<a>https://arxiv.org/abs/1602.02120v3</a>.</li>
°5u</ul>
°5u
°5uNote that the implementation is <i>left-biased</i> -- the elements of
°5ua first argument are always preferred to the second, for example in
°5u<a>union</a> or <a>insert</a>.
°5u
°5u<i>Warning</i>: The size of the map must not exceed
°5u<tt>maxBound::Int</tt>. Violation of this condition is not detected
°5uand if the size limit is exceeded, its behaviour is undefined.
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation (<a>http://en.wikipedia.org/wiki/Big_O_notation</a>).
module Data.Map

-- | <i>O(log n)</i>. Same as <a>insertWith</a>, but the value being
°5uinserted to the map is evaluated to WHNF beforehand.
°5u
°5uFor example, to update a counter:
°5u
°5u<pre>
°5uinsertWith' (+) k 1 m
°5u</pre>

-- | <i>Deprecated: As of version 0.5, replaced by <a>insertWith</a>.</i>
insertWith' :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Same as <a>insertWithKey</a>, but the value being
°5uinserted to the map is evaluated to WHNF beforehand.

-- | <i>Deprecated: As of version 0.5, replaced by
°5u<a>insertWithKey</a>.</i>
insertWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. Same as <a>insertLookupWithKey</a>, but the value
°5ubeing inserted to the map is evaluated to WHNF beforehand.

-- | <i>Deprecated: As of version 0.5, replaced by
°5u<a>insertLookupWithKey</a>.</i>
insertLookupWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.

-- | <i>Deprecated: As of version 0.5, replaced by <a>foldr</a>.</i>
fold :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldrWithKey</a> and is present for compatibility only.

-- | <i>Deprecated: As of version 0.4, replaced by <a>foldrWithKey</a>.</i>
foldWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uAn efficient implementation of integer sets.
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.IntSet (IntSet)
°5uimport qualified Data.IntSet as IntSet
°5u</pre>
°5u
°5uThe implementation is based on <i>big-endian patricia trees</i>. This
°5udata structure performs especially well on binary operations like
°5u<a>union</a> and <a>intersection</a>. However, my benchmarks show that
°5uit is also (much) faster on insertions and deletions when compared to
°5ua generic size-balanced set implementation (see <a>Data.Set</a>).
°5u
°5u<ul>
°5u<li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
°5uWorkshop on ML, September 1998, pages 77-86,
°5u<a>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
°5u<li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
°5uInformation Coded In Alphanumeric/", Journal of the ACM, 15(4),
°5uOctober 1968, pages 514-534.</li>
°5u</ul>
°5u
°5uAdditionally, this implementation places bitmaps in the leaves of the
°5utree. Their size is the natural size of a machine word (32 or 64 bits)
°5uand greatly reduce memory footprint and execution times for dense
°5usets, e.g. sets where it is likely that many values lie close to each
°5uother. The asymptotics are not affected by this optimization.
°5u
°5uMany operations have a worst-case complexity of <i>O(min(n,W))</i>.
°5uThis means that the operation can become linear in the number of
°5uelements with a maximum of <i>W</i> -- the number of bits in an
°5u<a>Int</a> (32 or 64).
module Data.IntSet.Internal

-- | A set of integers.
data IntSet
Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !IntSet -> !IntSet -> IntSet
Tip :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !BitMap -> IntSet
Nil :: IntSet
type Key = Int
type Prefix = Int
type Mask = Int
type BitMap = Word

-- | <i>O(n+m)</i>. See <a>difference</a>.
(\\) :: IntSet -> IntSet -> IntSet
infixl 9 \\

-- | <i>O(1)</i>. Is the set empty?
null :: IntSet -> Bool

-- | <i>O(n)</i>. Cardinality of the set.
size :: IntSet -> Int

-- | <i>O(min(n,W))</i>. Is the value a member of the set?
member :: Key -> IntSet -> Bool

-- | <i>O(min(n,W))</i>. Is the element not in the set?
notMember :: Key -> IntSet -> Bool

-- | <i>O(log n)</i>. Find largest element smaller than the given one.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [3, 5]) == Nothing
°5ulookupLT 5 (fromList [3, 5]) == Just 3
°5u</pre>
lookupLT :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find smallest element greater than the given one.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [3, 5]) == Just 5
°5ulookupGT 5 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGT :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find largest element smaller or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [3, 5]) == Nothing
°5ulookupLE 4 (fromList [3, 5]) == Just 3
°5ulookupLE 5 (fromList [3, 5]) == Just 5
°5u</pre>
lookupLE :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find smallest element greater or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [3, 5]) == Just 3
°5ulookupGE 4 (fromList [3, 5]) == Just 5
°5ulookupGE 6 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGE :: Key -> IntSet -> Maybe Key

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
°5utells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(n+m)</i>. Check whether two sets are disjoint (i.e. their
°5uintersection is empty).
°5u
°5u<pre>
°5udisjoint (fromList [2,4,6])   (fromList [1,3])     == True
°5udisjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
°5udisjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
°5udisjoint (fromList [])        (fromList [])        == True
°5u</pre>
disjoint :: IntSet -> IntSet -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: IntSet

-- | <i>O(1)</i>. A set of one element.
singleton :: Key -> IntSet

-- | <i>O(min(n,W))</i>. Add a value to the set. There is no left- or right
°5ubias for IntSets.
insert :: Key -> IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete a value in the set. Returns the original
°5uset when the value was not present.
delete :: Key -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The union of two sets.
union :: IntSet -> IntSet -> IntSet

-- | The union of a list of sets.
unions :: [IntSet] -> IntSet

-- | <i>O(n+m)</i>. Difference between two sets.
difference :: IntSet -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The intersection of two sets.
intersection :: IntSet -> IntSet -> IntSet

-- | <i>O(n)</i>. Filter all elements that satisfy some predicate.
filter :: (Key -> Bool) -> IntSet -> IntSet

-- | <i>O(n)</i>. partition the set according to some predicate.
partition :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>split</a> x set</tt>) is a
°5upair <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements
°5uof <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
°5uelements of <tt>set</tt> greater than <tt>x</tt>.
°5u
°5u<pre>
°5usplit 3 (fromList [1..5]) == (fromList [1,2], fromList [4,5])
°5u</pre>
split :: Key -> IntSet -> (IntSet, IntSet)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
°5uthe pivot element was found in the original set.
splitMember :: Key -> IntSet -> (IntSet, Bool, IntSet)

-- | <i>O(1)</i>. Decompose a set into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a set in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList [1..120]) == [fromList [1..63],fromList [64..120]]
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than two
°5usubsets, but you should not depend on this behaviour because it can
°5uchange in the future without notice. Also, the current version does
°5unot continue splitting all the way to individual singleton sets -- it
°5ustops at some point.
splitRoot :: IntSet -> [IntSet]

-- | <i>O(n*min(n,W))</i>. <tt><a>map</a> f s</tt> is the set obtained by
°5uapplying <tt>f</tt> to each element of <tt>s</tt>.
°5u
°5uIt's worth noting that the size of the result may be smaller if, for
°5usome <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: (Key -> Key) -> IntSet -> IntSet

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoAscList set = foldr (:) [] set
°5u</pre>
foldr :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoDescList set = foldl (flip (:)) [] set
°5u</pre>
foldl :: (a -> Key -> a) -> a -> IntSet -> a

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> Key -> a) -> a -> IntSet -> a

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.
°5u
°5u<i>Please note that fold will be deprecated in the future and
°5uremoved.</i>
fold :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(min(n,W))</i>. The minimal element of the set.
findMin :: IntSet -> Key

-- | <i>O(min(n,W))</i>. The maximal element of a set.
findMax :: IntSet -> Key

-- | <i>O(min(n,W))</i>. Delete the minimal element. Returns an empty set
°5uif the set is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
°5uwas already empty.
deleteMin :: IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete the maximal element. Returns an empty set
°5uif the set is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
°5uwas already empty.
deleteMax :: IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin set = (findMin set, deleteMin set)
°5u</pre>
deleteFindMin :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax set = (findMax set, deleteMax set)
°5u</pre>
deleteFindMax :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. Retrieves the maximal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: IntSet -> Maybe (Key, IntSet)

-- | <i>O(min(n,W))</i>. Retrieves the minimal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: IntSet -> Maybe (Key, IntSet)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
°5uascending order. Subject to list fusion.
elems :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
°5ufusion.
toList :: IntSet -> [Key]

-- | <i>O(n*min(n,W))</i>. Create a set from a list of integers.
fromList :: [Key] -> IntSet

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
°5uto list fusion.
toAscList :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
°5uto list fusion.
toDescList :: IntSet -> [Key]

-- | <i>O(n)</i>. Build a set from an ascending list of elements. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
fromAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements.
°5u<i>The precondition (input list is strictly ascending) is not
°5uchecked.</i>
fromDistinctAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
°5uin a compressed, hanging format.
showTree :: IntSet -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the set. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
showTreeWith :: Bool -> Bool -> IntSet -> String
match :: Int -> Prefix -> Mask -> Bool
suffixBitMask :: Int
prefixBitMask :: Int
bitmapOf :: Int -> BitMap
zero :: Int -> Mask -> Bool
instance GHC.Exts.IsList Data.IntSet.Internal.IntSet
instance GHC.Base.Monoid Data.IntSet.Internal.IntSet
instance GHC.Base.Semigroup Data.IntSet.Internal.IntSet
instance Data.Data.Data Data.IntSet.Internal.IntSet
instance GHC.Classes.Eq Data.IntSet.Internal.IntSet
instance GHC.Classes.Ord Data.IntSet.Internal.IntSet
instance GHC.Show.Show Data.IntSet.Internal.IntSet
instance GHC.Read.Read Data.IntSet.Internal.IntSet
instance Control.DeepSeq.NFData Data.IntSet.Internal.IntSet


-- | An efficient implementation of integer sets.
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.IntSet (IntSet)
°5uimport qualified Data.IntSet as IntSet
°5u</pre>
°5u
°5uThe implementation is based on <i>big-endian patricia trees</i>. This
°5udata structure performs especially well on binary operations like
°5u<a>union</a> and <a>intersection</a>. However, my benchmarks show that
°5uit is also (much) faster on insertions and deletions when compared to
°5ua generic size-balanced set implementation (see <a>Data.Set</a>).
°5u
°5u<ul>
°5u<li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
°5uWorkshop on ML, September 1998, pages 77-86,
°5u<a>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
°5u<li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
°5uInformation Coded In Alphanumeric/", Journal of the ACM, 15(4),
°5uOctober 1968, pages 514-534.</li>
°5u</ul>
°5u
°5uAdditionally, this implementation places bitmaps in the leaves of the
°5utree. Their size is the natural size of a machine word (32 or 64 bits)
°5uand greatly reduce memory footprint and execution times for dense
°5usets, e.g. sets where it is likely that many values lie close to each
°5uother. The asymptotics are not affected by this optimization.
°5u
°5uMany operations have a worst-case complexity of <i>O(min(n,W))</i>.
°5uThis means that the operation can become linear in the number of
°5uelements with a maximum of <i>W</i> -- the number of bits in an
°5u<a>Int</a> (32 or 64).
module Data.IntSet

-- | A set of integers.
data IntSet
type Key = Int

-- | <i>O(n+m)</i>. See <a>difference</a>.
(\\) :: IntSet -> IntSet -> IntSet
infixl 9 \\

-- | <i>O(1)</i>. Is the set empty?
null :: IntSet -> Bool

-- | <i>O(n)</i>. Cardinality of the set.
size :: IntSet -> Int

-- | <i>O(min(n,W))</i>. Is the value a member of the set?
member :: Key -> IntSet -> Bool

-- | <i>O(min(n,W))</i>. Is the element not in the set?
notMember :: Key -> IntSet -> Bool

-- | <i>O(log n)</i>. Find largest element smaller than the given one.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [3, 5]) == Nothing
°5ulookupLT 5 (fromList [3, 5]) == Just 3
°5u</pre>
lookupLT :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find smallest element greater than the given one.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [3, 5]) == Just 5
°5ulookupGT 5 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGT :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find largest element smaller or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [3, 5]) == Nothing
°5ulookupLE 4 (fromList [3, 5]) == Just 3
°5ulookupLE 5 (fromList [3, 5]) == Just 5
°5u</pre>
lookupLE :: Key -> IntSet -> Maybe Key

-- | <i>O(log n)</i>. Find smallest element greater or equal to the given
°5uone.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [3, 5]) == Just 3
°5ulookupGE 4 (fromList [3, 5]) == Just 5
°5ulookupGE 6 (fromList [3, 5]) == Nothing
°5u</pre>
lookupGE :: Key -> IntSet -> Maybe Key

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
°5utells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(n+m)</i>. Check whether two sets are disjoint (i.e. their
°5uintersection is empty).
°5u
°5u<pre>
°5udisjoint (fromList [2,4,6])   (fromList [1,3])     == True
°5udisjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
°5udisjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
°5udisjoint (fromList [])        (fromList [])        == True
°5u</pre>
disjoint :: IntSet -> IntSet -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: IntSet

-- | <i>O(1)</i>. A set of one element.
singleton :: Key -> IntSet

-- | <i>O(min(n,W))</i>. Add a value to the set. There is no left- or right
°5ubias for IntSets.
insert :: Key -> IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete a value in the set. Returns the original
°5uset when the value was not present.
delete :: Key -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The union of two sets.
union :: IntSet -> IntSet -> IntSet

-- | The union of a list of sets.
unions :: [IntSet] -> IntSet

-- | <i>O(n+m)</i>. Difference between two sets.
difference :: IntSet -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The intersection of two sets.
intersection :: IntSet -> IntSet -> IntSet

-- | <i>O(n)</i>. Filter all elements that satisfy some predicate.
filter :: (Key -> Bool) -> IntSet -> IntSet

-- | <i>O(n)</i>. partition the set according to some predicate.
partition :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>split</a> x set</tt>) is a
°5upair <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements
°5uof <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
°5uelements of <tt>set</tt> greater than <tt>x</tt>.
°5u
°5u<pre>
°5usplit 3 (fromList [1..5]) == (fromList [1,2], fromList [4,5])
°5u</pre>
split :: Key -> IntSet -> (IntSet, IntSet)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
°5uthe pivot element was found in the original set.
splitMember :: Key -> IntSet -> (IntSet, Bool, IntSet)

-- | <i>O(1)</i>. Decompose a set into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a set in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList [1..120]) == [fromList [1..63],fromList [64..120]]
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than two
°5usubsets, but you should not depend on this behaviour because it can
°5uchange in the future without notice. Also, the current version does
°5unot continue splitting all the way to individual singleton sets -- it
°5ustops at some point.
splitRoot :: IntSet -> [IntSet]

-- | <i>O(n*min(n,W))</i>. <tt><a>map</a> f s</tt> is the set obtained by
°5uapplying <tt>f</tt> to each element of <tt>s</tt>.
°5u
°5uIt's worth noting that the size of the result may be smaller if, for
°5usome <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: (Key -> Key) -> IntSet -> IntSet

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoAscList set = foldr (:) [] set
°5u</pre>
foldr :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5utoDescList set = foldl (flip (:)) [] set
°5u</pre>
foldl :: (a -> Key -> a) -> a -> IntSet -> a

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> Key -> a) -> a -> IntSet -> a

-- | <i>O(n)</i>. Fold the elements in the set using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.
°5u
°5u<i>Please note that fold will be deprecated in the future and
°5uremoved.</i>
fold :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(min(n,W))</i>. The minimal element of the set.
findMin :: IntSet -> Key

-- | <i>O(min(n,W))</i>. The maximal element of a set.
findMax :: IntSet -> Key

-- | <i>O(min(n,W))</i>. Delete the minimal element. Returns an empty set
°5uif the set is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
°5uwas already empty.
deleteMin :: IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete the maximal element. Returns an empty set
°5uif the set is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
°5uwas already empty.
deleteMax :: IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete and find the minimal element.
°5u
°5u<pre>
°5udeleteFindMin set = (findMin set, deleteMin set)
°5u</pre>
deleteFindMin :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element.
°5u
°5u<pre>
°5udeleteFindMax set = (findMax set, deleteMax set)
°5u</pre>
deleteFindMax :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. Retrieves the maximal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: IntSet -> Maybe (Key, IntSet)

-- | <i>O(min(n,W))</i>. Retrieves the minimal key of the set, and the set
°5ustripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: IntSet -> Maybe (Key, IntSet)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
°5uascending order. Subject to list fusion.
elems :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
°5ufusion.
toList :: IntSet -> [Key]

-- | <i>O(n*min(n,W))</i>. Create a set from a list of integers.
fromList :: [Key] -> IntSet

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
°5uto list fusion.
toAscList :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
°5uto list fusion.
toDescList :: IntSet -> [Key]

-- | <i>O(n)</i>. Build a set from an ascending list of elements. <i>The
°5uprecondition (input list is ascending) is not checked.</i>
fromAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements.
°5u<i>The precondition (input list is strictly ascending) is not
°5uchecked.</i>
fromDistinctAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
°5uin a compressed, hanging format.
showTree :: IntSet -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the set. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
showTreeWith :: Bool -> Bool -> IntSet -> String


-- | <h1>WARNING</h1>
°5u
°5uThis module is considered <b>internal</b>.
°5u
°5uThe Package Versioning Policy <b>does not apply</b>.
°5u
°5uThis contents of this module may change <b>in any way whatsoever</b>
°5uand <b>without any warning</b> between minor versions of this package.
°5u
°5uAuthors importing this module are expected to track development
°5uclosely.
°5u
°5u<h1>Description</h1>
°5u
°5uThis defines the data structures and core (hidden) manipulations on
°5urepresentations.
module Data.IntMap.Internal

-- | A map of integers to values <tt>a</tt>.
data IntMap a
Bin :: {-# UNPACK #-} !Prefix -> {-# UNPACK #-} !Mask -> !(IntMap a) -> !(IntMap a) -> IntMap a
Tip :: {-# UNPACK #-} !Key -> a -> IntMap a
Nil :: IntMap a
type Key = Int

-- | <i>O(min(n,W))</i>. Find the value at a key. Calls <a>error</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: IntMap a -> Key -> a

-- | <i>O(min(n,W))</i>. Find the value at a key. Returns <a>Nothing</a>
°5uwhen the element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] !? 1 == Nothing
°5ufromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.IntMap.null (empty)           == True
°5uData.IntMap.null (singleton 1 'a') == False
°5u</pre>
null :: IntMap a -> Bool

-- | <i>O(n)</i>. Number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: IntMap a -> Int

-- | <i>O(min(n,W))</i>. Is the key a member of the map?
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Is the key not a member of the map?
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Lookup the value at a key in the map. See also
°5u<a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | <i>O(min(n,W))</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
°5uwhen the key is not an element of the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: IntMap a

-- | <i>O(1)</i>. A map of one element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: Key -> a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert a new key/value pair in the map. If the key
°5uis already present in the map, the associated value is replaced with
°5uthe supplied value, i.e. <a>insert</a> is equivalent to
°5u<tt><a>insertWith</a> <a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWith</a> f key value mp</tt> will insert the pair (key,
°5uvalue) into <tt>mp</tt> if key does not exist in the map. If the key
°5udoes exist, the function will insert <tt>f new_value old_value</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert <tt>f key new_value
°5uold_value</tt>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>insertLookupWithKey</a> f k
°5ux map</tt>) is a pair where the first element is equal to
°5u(<tt><a>lookup</a> k map</tt>) and the second element equal to
°5u(<tt><a>insertWithKey</a> f k x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. Delete a key and its value from the map. When the
°5ukey is not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Lookup and update. The function returns original
°5uvalue, if it is updated. This is different behavior than
°5u<a>updateLookupWithKey</a>. Returns the original key value if the map
°5uentry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>alter</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alter</a> can be used to insert, delete, or update a value in an
°5u<a>IntMap</a>. In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f
°5u(<a>lookup</a> k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in an <a>IntMap</a>. In short : <tt><a>lookup</a> k <a>$</a>
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | <i>O(n+m)</i>. The (left-biased) union of two maps. It prefers the
°5ufirst map when duplicate keys are encountered, i.e. (<tt><a>union</a>
°5u== <a>unionWith</a> <a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: [IntMap a] -> IntMap a

-- | The union of a list of maps, with a combining operation.
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: (a -> a -> a) -> [IntMap a] -> IntMap a

-- | <i>O(n+m)</i>. Difference between two maps (based on keys).
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The (left-biased) intersection of two maps (based on
°5ukeys).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; Maybe
°5uz</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
°5uMaybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; Maybe z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMatched :: Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (Key -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMissing f k x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
°5uz)</tt>.
data WhenMissing f x y
WhenMissing :: IntMap x -> f (IntMap y) -> Key -> x -> f (Maybe y) -> WhenMissing f x y
[missingSubtree] :: WhenMissing f x y -> IntMap x -> f (IntMap y)
[missingKey] :: WhenMissing f x y -> Key -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMatched f x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
newtype WhenMatched f x y z
WhenMatched :: Key -> x -> y -> f (Maybe z) -> WhenMatched f x y z
[matchedKey] :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f) => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | <i>O(n+m)</i>. A high-performance universal combining function. Using
°5u<a>mergeWithKey</a>, all combining functions can be defined without
°5uany loss of efficiency (with exception of <a>union</a>,
°5u<a>difference</a> and <a>intersection</a>, where sharing of some nodes
°5uis lost with <a>mergeWithKey</a>).
°5u
°5uPlease make sure you know what is going on when using
°5u<a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
°5ugrowth or even corruption of the data structure.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine your custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>IntMap</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
°5u<tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c
mergeWithKey' :: (Prefix -> Mask -> IntMap c -> IntMap c -> IntMap c) -> (IntMap a -> IntMap b -> IntMap c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
°5u(<a>toList</a> m)</tt> That is, behaves exactly like a regular
°5u<a>traverse</a> except that the traversing function also has access to
°5uthe key associated with a value.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | <i>O(n)</i>. The function <tt><a>mapAccum</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><a>mapAccumWithKey</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><tt>mapAccumR</tt></tt> threads an
°5uaccumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained
°5uby applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeysMonotonic</a> f s ==
°5u<a>mapKeys</a> f s</tt>, but works only when <tt>f</tt> is strictly
°5umonotonic. That is, for any values <tt>x</tt> and <tt>y</tt>, if
°5u<tt>x</tt> &lt; <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The
°5uprecondition is not checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has slightly better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5u</pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: IntMap a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: IntMap a -> [Key]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Returns all key/value
°5upairs in the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
°5ukeysSet empty == Data.IntSet.empty
°5u</pre>
keysSet :: IntMap a -> IntSet

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.IntSet.empty == empty
°5u</pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs with
°5ua combining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "ab"), (5, "cba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Build a map from a list of key/value pairs with
°5ua combining function. See also fromAscListWithKey'.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order.
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5u</pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5u</pre>
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]
°5u</pre>
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order and all distinct. <i>The precondition (input
°5ulist is strictly ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5u</pre>
fromDistinctAscList :: forall a. [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Filter all values that satisfy some predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Filter all keys/values that satisfy some predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The restriction of a map to the keys in a set.
°5u
°5u<pre>
°5um <a>restrictKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5u</pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n+m)</i>. Remove all the keys in a given set from a map.
°5u
°5u<pre>
°5um <a>withoutKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5u</pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower
°5uthan <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
°5uthe pivot key was found in the original map.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6::Int] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than two
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | <i>O(n+m)</i>. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
°5u<a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
°5ureturns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
°5uwhen <tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5u</pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uDefined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
°5u(==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uThe expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
°5u<a>True</a> when <tt>m1</tt> and <tt>m2</tt> are not equal, all keys
°5uin <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(min(n,W))</i>. The minimal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The minimal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>minViewWithKey</a> if the map may be empty.
findMin :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>maxViewWithKey</a> if the map may be empty.
findMax :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. Delete the minimal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMin :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete the maximal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMax :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete and find the minimal element. This function
°5uthrows an error if the map is empty. Use <a>minViewWithKey</a> if the
°5umap may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element. This function
°5uthrows an error if the map is empty. Use <a>maxViewWithKey</a> if the
°5umap may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Retrieves the minimal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the map. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String
type Mask = Int
type Prefix = Int
type Nat = Word
natFromInt :: Key -> Nat
intFromNat :: Nat -> Key
link :: Prefix -> IntMap a -> Prefix -> IntMap a -> IntMap a
bin :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
binCheckLeft :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
binCheckRight :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a

-- | Should this key follow the left subtree of a <a>Bin</a> with switching
°5ubit <tt>m</tt>? N.B., the answer is only valid when <tt>match i p
°5um</tt> is true.
zero :: Key -> Mask -> Bool

-- | Does the key <tt>i</tt> differ from the prefix <tt>p</tt> before
°5ugetting to the switching bit <tt>m</tt>?
nomatch :: Key -> Prefix -> Mask -> Bool

-- | Does the key <tt>i</tt> match the prefix <tt>p</tt> (up to but not
°5uincluding bit <tt>m</tt>)?
match :: Key -> Prefix -> Mask -> Bool

-- | The prefix of key <tt>i</tt> up to (but not including) the switching
°5ubit <tt>m</tt>.
mask :: Key -> Mask -> Prefix

-- | The prefix of key <tt>i</tt> up to (but not including) the switching
°5ubit <tt>m</tt>.
maskW :: Nat -> Nat -> Prefix

-- | Does the left switching bit specify a shorter prefix?
shorter :: Mask -> Mask -> Bool

-- | The first switching bit where the two prefixes disagree.
branchMask :: Prefix -> Prefix -> Mask

-- | Return a word where only the highest bit is set.
highestBitMask :: Word -> Word

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>.
mapWhenMissing :: (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f _ x</tt>.
lmapWhenMissing :: (b -> a) -> WhenMissing f a x -> WhenMissing f b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f _ y z</tt>.
contramapFirstWhenMatched :: (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f x _ z</tt>.
contramapSecondWhenMatched :: (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>, using only a
°5u'Functor f' constraint.
mapGentlyWhenMissing :: Functor f => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x</tt>, using only a
°5u'Functor f' constraint.
mapGentlyWhenMatched :: Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
instance GHC.Base.Functor f => GHC.Base.Functor (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => Control.Category.Category (Data.IntMap.Internal.WhenMatched f x)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Applicative (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Base.Monad f, GHC.Base.Applicative f) => GHC.Base.Monad (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Functor (Data.IntMap.Internal.WhenMissing f x)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => Control.Category.Category (Data.IntMap.Internal.WhenMissing f)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Applicative (Data.IntMap.Internal.WhenMissing f x)
instance (GHC.Base.Applicative f, GHC.Base.Monad f) => GHC.Base.Monad (Data.IntMap.Internal.WhenMissing f x)
instance GHC.Base.Monoid (Data.IntMap.Internal.IntMap a)
instance GHC.Base.Semigroup (Data.IntMap.Internal.IntMap a)
instance Data.Foldable.Foldable Data.IntMap.Internal.IntMap
instance Data.Traversable.Traversable Data.IntMap.Internal.IntMap
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.IntMap.Internal.IntMap a)
instance Data.Data.Data a => Data.Data.Data (Data.IntMap.Internal.IntMap a)
instance GHC.Exts.IsList (Data.IntMap.Internal.IntMap a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Eq1 Data.IntMap.Internal.IntMap
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Ord1 Data.IntMap.Internal.IntMap
instance GHC.Base.Functor Data.IntMap.Internal.IntMap
instance GHC.Show.Show a => GHC.Show.Show (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Show1 Data.IntMap.Internal.IntMap
instance GHC.Read.Read e => GHC.Read.Read (Data.IntMap.Internal.IntMap e)
instance Data.Functor.Classes.Read1 Data.IntMap.Internal.IntMap


-- | This module defines an API for writing functions that merge two maps.
°5uThe key functions are <a>merge</a> and <a>mergeA</a>. Each of these
°5ucan be used with several different "merge tactics".
°5u
°5uThe <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
°5uand strict modules. Only the choice of merge tactics determines
°5ustrictness. If you use <a>mapMissing</a> from this module then the
°5uresults will be forced before they are inserted. If you use
°5u<a>mapMissing</a> from <a>Data.Map.Merge.Lazy</a> then they will not.
°5u
°5u<h2>Efficiency note</h2>
°5u
°5uThe <tt>Category</tt>, <a>Applicative</a>, and <a>Monad</a> instances
°5ufor <a>WhenMissing</a> tactics are included because they are valid.
°5uHowever, they are inefficient in many cases and should usually be
°5uavoided. The instances for <a>WhenMatched</a> tactics should not pose
°5uany major efficiency problems.
module Data.IntMap.Merge.Strict

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; Maybe
°5uz</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
°5uMaybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; Maybe z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMatched :: Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (Key -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMissing f k x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
°5uz)</tt>.
data WhenMissing f x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMatched f x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
data WhenMatched f x y z

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f) => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>.
mapWhenMissing :: (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)


-- | This module defines an API for writing functions that merge two maps.
°5uThe key functions are <a>merge</a> and <a>mergeA</a>. Each of these
°5ucan be used with several different "merge tactics".
°5u
°5uThe <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
°5uand strict modules. Only the choice of merge tactics determines
°5ustrictness. If you use <a>mapMissing</a> from
°5u<a>Data.Map.Merge.Strict</a> then the results will be forced before
°5uthey are inserted. If you use <a>mapMissing</a> from this module then
°5uthey will not.
°5u
°5u<h2>Efficiency note</h2>
°5u
°5uThe <tt>Category</tt>, <a>Applicative</a>, and <a>Monad</a> instances
°5ufor <a>WhenMissing</a> tactics are included because they are valid.
°5uHowever, they are inefficient in many cases and should usually be
°5uavoided. The instances for <a>WhenMatched</a> tactics should not pose
°5uany major efficiency problems.
module Data.IntMap.Merge.Lazy

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; Maybe
°5uz</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
°5u
°5uA tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
°5uMaybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
°5u
°5u<tt>merge</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umerge (mapMaybeMissing g1)
°5u             (mapMaybeMissing g2)
°5u             (zipWithMaybeMatched f)
°5u             m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>merge</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5umaybes = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uThis produces a <a>Maybe</a> for each key:
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>mapMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u</ul>
°5u
°5uWhen <a>merge</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should typically use
°5u<a>merge</a> to define your custom combining functions.
°5u
°5uExamples:
°5u
°5u<pre>
°5uunionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5uintersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
°5u</pre>
°5u
°5u<pre>
°5udifferenceWith f = merge diffPreserve diffDrop f
°5u</pre>
°5u
°5u<pre>
°5usymmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
°5u</pre>
°5u
°5u<pre>
°5umapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
°5u</pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and maybe use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMaybeMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; Maybe z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMaybeMatched :: Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues and use the result in the merged map.
°5u
°5u<pre>
°5uzipWithMatched
°5u  :: (Key -&gt; x -&gt; y -&gt; z)
°5u  -&gt; SimpleWhenMatched x y z
°5u</pre>
zipWithMatched :: Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
°5uoptionally removing some. This is the most powerful
°5u<a>SimpleWhenMissing</a> tactic, but others are usually more
°5uefficient.
°5u
°5u<pre>
°5umapMaybeMissing :: (Key -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
°5u</pre>
°5u
°5ubut <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
°5uoperations.
mapMaybeMissing :: Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5udropMissing :: SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5udropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
°5u</pre>
°5u
°5ubut <tt>dropMissing</tt> is much faster.
dropMissing :: Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
°5umap.
°5u
°5u<pre>
°5upreserveMissing :: SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5upreserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
°5u</pre>
°5u
°5ubut <tt>preserveMissing</tt> is much faster.
preserveMissing :: Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5umapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing x y
°5u</pre>
°5u
°5u<pre>
°5umapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
°5u</pre>
°5u
°5ubut <tt>mapMissing</tt> is somewhat faster.
mapMissing :: Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
°5u
°5u<pre>
°5ufilterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
°5u</pre>
°5u
°5u<pre>
°5ufilterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterMissing :: Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
°5u<a>merge</a> or <a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMissing f k x z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
°5uz)</tt>.
data WhenMissing f x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
°5u<a>mergeA</a>.
°5u
°5uA tactic of type <tt>WhenMatched f x y z</tt> is an abstract
°5urepresentation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
data WhenMatched f x y z

-- | An applicative version of <a>merge</a>.
°5u
°5u<tt>mergeA</tt> takes two <a>WhenMissing</a> tactics, a
°5u<a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
°5uthe maps. Its behavior is best understood via its fundamental tactics,
°5u<a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
°5u
°5uConsider
°5u
°5u<pre>
°5umergeA (traverseMaybeMissing g1)
°5u              (traverseMaybeMissing g2)
°5u              (zipWithMaybeAMatched f)
°5u              m1 m2
°5u</pre>
°5u
°5uTake, for example,
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>), (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 = [(1, "one"), (2, "two"), (4, "three")]
°5u</pre>
°5u
°5u<tt>mergeA</tt> will first '<tt>align'</tt> these maps by key:
°5u
°5u<pre>
°5um1 = [(0, <tt>a</tt>), (1, <tt>b</tt>),               (3,<tt>c</tt>), (4, <tt>d</tt>)]
°5um2 =           [(1, "one"), (2, "two"),          (4, "three")]
°5u</pre>
°5u
°5uIt will then pass the individual entries and pairs of entries to
°5u<tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
°5u
°5u<pre>
°5uactions = [g1 0 <tt>a</tt>, f 1 <tt>b</tt> "one", g2 2 "two", g1 3 <tt>c</tt>, f 4 <tt>d</tt> "three"]
°5u</pre>
°5u
°5uNext, it will perform the actions in the <tt>actions</tt> list in
°5uorder from left to right.
°5u
°5u<pre>
°5ukeys =     0        1          2           3        4
°5uresults = [Nothing, Just True, Just False, Nothing, Just True]
°5u</pre>
°5u
°5uFinally, the <tt>Just</tt> results are collected into a map:
°5u
°5u<pre>
°5ureturn value = [(1, True), (2, False), (4, True)]
°5u</pre>
°5u
°5uThe other tactics below are optimizations or simplifications of
°5u<a>traverseMaybeMissing</a> for special cases. Most importantly,
°5u
°5u<ul>
°5u<li><a>dropMissing</a> drops all the keys.</li>
°5u<li><a>preserveMissing</a> leaves all the entries alone.</li>
°5u<li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
°5ucontext.</li>
°5u</ul>
°5u
°5uWhen <a>mergeA</a> is given three arguments, it is inlined at the call
°5usite. To prevent excessive inlining, you should generally only use
°5u<a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f) => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
°5uvalues, perform the resulting action, and maybe use the result in the
°5umerged map.
°5u
°5uThis is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
°5uvalues to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
°5uoptionally producing values to put in the result. This is the most
°5upowerful <a>WhenMissing</a> tactic, but others are usually more
°5uefficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
°5usome <a>Applicative</a> action.
°5u
°5u<pre>
°5ufilterAMissing f = Merge.Lazy.traverseMaybeMissing $
°5u  \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
°5u</pre>
°5u
°5ubut this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>.
mapWhenMissing :: (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f x y</tt>.
mapWhenMatched :: Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f _ x</tt>.
lmapWhenMissing :: (b -> a) -> WhenMissing f a x -> WhenMissing f b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f _ y z</tt>.
contramapFirstWhenMatched :: (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f x _ z</tt>.
contramapSecondWhenMatched :: (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
°5u<tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
°5u(Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
°5u<tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)


-- | An efficient implementation of maps from integer keys to values
°5u(dictionaries).
°5u
°5uAPI of this module is strict in both the keys and the values. If you
°5uneed value-lazy maps, use <a>Data.IntMap.Lazy</a> instead. The
°5u<a>IntMap</a> type itself is shared between the lazy and strict
°5umodules, meaning that the same <a>IntMap</a> value can be passed to
°5ufunctions in both modules (although that is rarely needed).
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.IntMap.Strict (IntMap)
°5uimport qualified Data.IntMap.Strict as IntMap
°5u</pre>
°5u
°5uThe implementation is based on <i>big-endian patricia trees</i>. This
°5udata structure performs especially well on binary operations like
°5u<a>union</a> and <a>intersection</a>. However, my benchmarks show that
°5uit is also (much) faster on insertions and deletions when compared to
°5ua generic size-balanced map implementation (see <a>Data.Map</a>).
°5u
°5u<ul>
°5u<li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
°5uWorkshop on ML, September 1998, pages 77-86,
°5u<a>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
°5u<li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
°5uInformation Coded In Alphanumeric/", Journal of the ACM, 15(4),
°5uOctober 1968, pages 514-534.</li>
°5u</ul>
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
°5uoperations have a worst-case complexity of <i>O(min(n,W))</i>. This
°5umeans that the operation can become linear in the number of elements
°5uwith a maximum of <i>W</i> -- the number of bits in an <a>Int</a> (32
°5uor 64).
°5u
°5uBe aware that the <a>Functor</a>, <a>Traversable</a> and <tt>Data</tt>
°5uinstances are the same as for the <a>Data.IntMap.Lazy</a> module, so
°5uif they are used on strict maps, the resulting maps will be lazy.
module Data.IntMap.Strict

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | <i>O(min(n,W))</i>. Find the value at a key. Calls <a>error</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: IntMap a -> Key -> a

-- | <i>O(min(n,W))</i>. Find the value at a key. Returns <a>Nothing</a>
°5uwhen the element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] !? 1 == Nothing
°5ufromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.IntMap.null (empty)           == True
°5uData.IntMap.null (singleton 1 'a') == False
°5u</pre>
null :: IntMap a -> Bool

-- | <i>O(n)</i>. Number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: IntMap a -> Int

-- | <i>O(min(n,W))</i>. Is the key a member of the map?
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Is the key not a member of the map?
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Lookup the value at a key in the map. See also
°5u<a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | <i>O(min(n,W))</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
°5uwhen the key is not an element of the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: IntMap a

-- | <i>O(1)</i>. A map of one element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: Key -> a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert a new key/value pair in the map. If the key
°5uis already present in the map, the associated value is replaced with
°5uthe supplied value, i.e. <a>insert</a> is equivalent to
°5u<tt><a>insertWith</a> <a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWith</a> f key value mp</tt> will insert the pair (key,
°5uvalue) into <tt>mp</tt> if key does not exist in the map. If the key
°5udoes exist, the function will insert <tt>f new_value old_value</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert <tt>f key new_value
°5uold_value</tt>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
°5u
°5uIf the key exists in the map, this function is lazy in <tt>x</tt> but
°5ustrict in the result of <tt>f</tt>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>insertLookupWithKey</a> f k
°5ux map</tt>) is a pair where the first element is equal to
°5u(<tt><a>lookup</a> k map</tt>) and the second element equal to
°5u(<tt><a>insertWithKey</a> f k x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. Delete a key and its value from the map. When the
°5ukey is not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Lookup and update. The function returns original
°5uvalue, if it is updated. This is different behavior than
°5u<a>updateLookupWithKey</a>. Returns the original key value if the map
°5uentry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>alter</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alter</a> can be used to insert, delete, or update a value in an
°5u<a>IntMap</a>. In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f
°5u(<a>lookup</a> k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in an <a>IntMap</a>. In short : <tt><a>lookup</a> k <a>$</a>
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | <i>O(n+m)</i>. The (left-biased) union of two maps. It prefers the
°5ufirst map when duplicate keys are encountered, i.e. (<tt><a>union</a>
°5u== <a>unionWith</a> <a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: [IntMap a] -> IntMap a

-- | The union of a list of maps, with a combining operation.
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: (a -> a -> a) -> [IntMap a] -> IntMap a

-- | <i>O(n+m)</i>. Difference between two maps (based on keys).
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The (left-biased) intersection of two maps (based on
°5ukeys).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n+m)</i>. A high-performance universal combining function. Using
°5u<a>mergeWithKey</a>, all combining functions can be defined without
°5uany loss of efficiency (with exception of <a>union</a>,
°5u<a>difference</a> and <a>intersection</a>, where sharing of some nodes
°5uis lost with <a>mergeWithKey</a>).
°5u
°5uPlease make sure you know what is going on when using
°5u<a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
°5ugrowth or even corruption of the data structure.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine your custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>IntMap</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
°5u<tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
°5u(<a>toList</a> m)</tt> That is, behaves exactly like a regular
°5u<a>traverse</a> except that the traversing function also has access to
°5uthe key associated with a value.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | <i>O(n)</i>. The function <tt><a>mapAccum</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><a>mapAccumWithKey</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><tt>mapAccumR</tt></tt> threads an
°5uaccumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained
°5uby applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*log n)</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeysMonotonic</a> f s ==
°5u<a>mapKeys</a> f s</tt>, but works only when <tt>f</tt> is strictly
°5umonotonic. That is, for any values <tt>x</tt> and <tt>y</tt>, if
°5u<tt>x</tt> &lt; <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The
°5uprecondition is not checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has slightly better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5u</pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: IntMap a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: IntMap a -> [Key]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Returns all key/value
°5upairs in the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
°5ukeysSet empty == Data.IntSet.empty
°5u</pre>
keysSet :: IntMap a -> IntSet

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.IntSet.empty == empty
°5u</pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs with
°5ua combining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Build a map from a list of key/value pairs with
°5ua combining function. See also fromAscListWithKey'.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order.
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5u</pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5u</pre>
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5u</pre>
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order and all distinct. <i>The precondition (input
°5ulist is strictly ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5u</pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Filter all values that satisfy some predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Filter all keys/values that satisfy some predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The restriction of a map to the keys in a set.
°5u
°5u<pre>
°5um <a>restrictKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5u</pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n+m)</i>. Remove all the keys in a given set from a map.
°5u
°5u<pre>
°5um <a>withoutKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5u</pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower
°5uthan <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
°5uthe pivot key was found in the original map.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6::Int] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than two
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | <i>O(n+m)</i>. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
°5u<a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
°5ureturns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
°5uwhen <tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5u</pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uDefined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
°5u(==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uThe expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
°5u<a>True</a> when <tt>m1</tt> and <tt>m2</tt> are not equal, all keys
°5uin <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(min(n,W))</i>. The minimal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The minimal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>minViewWithKey</a> if the map may be empty.
findMin :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>maxViewWithKey</a> if the map may be empty.
findMax :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. Delete the minimal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMin :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete the maximal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMax :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete and find the minimal element. This function
°5uthrows an error if the map is empty. Use <a>minViewWithKey</a> if the
°5umap may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element. This function
°5uthrows an error if the map is empty. Use <a>maxViewWithKey</a> if the
°5umap may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Retrieves the minimal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format.

-- | <i>Deprecated: These debugging functions will be removed from this
°5umodule. They are available from Data.IntMap.Internal.Debug.</i>
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the map. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.

-- | <i>Deprecated: These debugging functions will be removed from this
°5umodule. They are available from Data.IntMap.Internal.Debug.</i>
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String


-- | An efficient implementation of maps from integer keys to values
°5u(dictionaries).
°5u
°5uAPI of this module is strict in the keys, but lazy in the values. If
°5uyou need value-strict maps, use <a>Data.IntMap.Strict</a> instead. The
°5u<a>IntMap</a> type itself is shared between the lazy and strict
°5umodules, meaning that the same <a>IntMap</a> value can be passed to
°5ufunctions in both modules (although that is rarely needed).
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.IntMap.Lazy (IntMap)
°5uimport qualified Data.IntMap.Lazy as IntMap
°5u</pre>
°5u
°5uThe implementation is based on <i>big-endian patricia trees</i>. This
°5udata structure performs especially well on binary operations like
°5u<a>union</a> and <a>intersection</a>. However, my benchmarks show that
°5uit is also (much) faster on insertions and deletions when compared to
°5ua generic size-balanced map implementation (see <a>Data.Map</a>).
°5u
°5u<ul>
°5u<li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
°5uWorkshop on ML, September 1998, pages 77-86,
°5u<a>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
°5u<li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
°5uInformation Coded In Alphanumeric/", Journal of the ACM, 15(4),
°5uOctober 1968, pages 514-534.</li>
°5u</ul>
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
°5uoperations have a worst-case complexity of <i>O(min(n,W))</i>. This
°5umeans that the operation can become linear in the number of elements
°5uwith a maximum of <i>W</i> -- the number of bits in an <a>Int</a> (32
°5uor 64).
module Data.IntMap.Lazy

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | <i>O(min(n,W))</i>. Find the value at a key. Calls <a>error</a> when
°5uthe element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
°5ufromList [(5,'a'), (3,'b')] ! 5 == 'a'
°5u</pre>
(!) :: IntMap a -> Key -> a

-- | <i>O(min(n,W))</i>. Find the value at a key. Returns <a>Nothing</a>
°5uwhen the element can not be found.
°5u
°5u<pre>
°5ufromList [(5,'a'), (3,'b')] !? 1 == Nothing
°5ufromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
°5u</pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | <i>O(1)</i>. Is the map empty?
°5u
°5u<pre>
°5uData.IntMap.null (empty)           == True
°5uData.IntMap.null (singleton 1 'a') == False
°5u</pre>
null :: IntMap a -> Bool

-- | <i>O(n)</i>. Number of elements in the map.
°5u
°5u<pre>
°5usize empty                                   == 0
°5usize (singleton 1 'a')                       == 1
°5usize (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
°5u</pre>
size :: IntMap a -> Int

-- | <i>O(min(n,W))</i>. Is the key a member of the map?
°5u
°5u<pre>
°5umember 5 (fromList [(5,'a'), (3,'b')]) == True
°5umember 1 (fromList [(5,'a'), (3,'b')]) == False
°5u</pre>
member :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Is the key not a member of the map?
°5u
°5u<pre>
°5unotMember 5 (fromList [(5,'a'), (3,'b')]) == False
°5unotMember 1 (fromList [(5,'a'), (3,'b')]) == True
°5u</pre>
notMember :: Key -> IntMap a -> Bool

-- | <i>O(min(n,W))</i>. Lookup the value at a key in the map. See also
°5u<a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | <i>O(min(n,W))</i>. The expression <tt>(<a>findWithDefault</a> def k
°5umap)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
°5uwhen the key is not an element of the map.
°5u
°5u<pre>
°5ufindWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
°5ufindWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
°5u</pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | <i>O(log n)</i>. Find largest key smaller than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5u</pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater than the given one and
°5ureturn the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find largest key smaller or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
°5ulookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5u</pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(log n)</i>. Find smallest key greater or equal to the given one
°5uand return the corresponding (key, value) pair.
°5u
°5u<pre>
°5ulookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
°5ulookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
°5ulookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
°5u</pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | <i>O(1)</i>. The empty map.
°5u
°5u<pre>
°5uempty      == fromList []
°5usize empty == 0
°5u</pre>
empty :: IntMap a

-- | <i>O(1)</i>. A map of one element.
°5u
°5u<pre>
°5usingleton 1 'a'        == fromList [(1, 'a')]
°5usize (singleton 1 'a') == 1
°5u</pre>
singleton :: Key -> a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert a new key/value pair in the map. If the key
°5uis already present in the map, the associated value is replaced with
°5uthe supplied value, i.e. <a>insert</a> is equivalent to
°5u<tt><a>insertWith</a> <a>const</a></tt>.
°5u
°5u<pre>
°5uinsert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
°5uinsert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
°5uinsert 5 'x' empty                         == singleton 5 'x'
°5u</pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWith</a> f key value mp</tt> will insert the pair (key,
°5uvalue) into <tt>mp</tt> if key does not exist in the map. If the key
°5udoes exist, the function will insert <tt>f new_value old_value</tt>.
°5u
°5u<pre>
°5uinsertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
°5uinsertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Insert with a combining function.
°5u<tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
°5u(key, value) into <tt>mp</tt> if key does not exist in the map. If the
°5ukey does exist, the function will insert <tt>f key new_value
°5uold_value</tt>.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
°5uinsertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
°5uinsertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
°5u</pre>
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>insertLookupWithKey</a> f k
°5ux map</tt>) is a pair where the first element is equal to
°5u(<tt><a>lookup</a> k map</tt>) and the second element equal to
°5u(<tt><a>insertWithKey</a> f k x map</tt>).
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5uinsertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
°5uinsertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
°5uinsertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
°5u</pre>
°5u
°5uThis is how to define <tt>insertLookup</tt> using
°5u<tt>insertLookupWithKey</tt>:
°5u
°5u<pre>
°5ulet insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
°5uinsertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
°5uinsertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
°5u</pre>
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. Delete a key and its value from the map. When the
°5ukey is not a member of the map, the original map is returned.
°5u
°5u<pre>
°5udelete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5udelete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5udelete 5 empty                         == empty
°5u</pre>
delete :: Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5uadjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uadjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjust ("new " ++) 7 empty                         == empty
°5u</pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Adjust a value at a specific key. When the key is
°5unot a member of the map, the original map is returned.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":new " ++ x
°5uadjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uadjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uadjustWithKey f 7 empty                         == empty
°5u</pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5uupdate f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
°5uupdate f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdate f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. The expression (<tt><a>update</a> f k map</tt>)
°5uupdates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
°5u(<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
°5u(<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
°5u<tt>y</tt>.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
°5uupdateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
°5uupdateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Lookup and update. The function returns original
°5uvalue, if it is updated. This is different behavior than
°5u<a>updateLookupWithKey</a>. Returns the original key value if the map
°5uentry is deleted.
°5u
°5u<pre>
°5ulet f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
°5uupdateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
°5uupdateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
°5uupdateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
°5u</pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>alter</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alter</a> can be used to insert, delete, or update a value in an
°5u<a>IntMap</a>. In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f
°5u(<a>lookup</a> k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. The expression (<tt><a>alterF</a> f k map</tt>)
°5ualters the value <tt>x</tt> at <tt>k</tt>, or absence thereof.
°5u<a>alterF</a> can be used to inspect, insert, delete, or update a
°5uvalue in an <a>IntMap</a>. In short : <tt><a>lookup</a> k <a>$</a>
°5u<a>alterF</a> f k m = f (<a>lookup</a> k m)</tt>.
°5u
°5uExample:
°5u
°5u<pre>
°5uinteractiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
°5uinteractiveAlter k m = alterF f k m where
°5u  f Nothing -&gt; do
°5u     putStrLn $ show k ++
°5u         " was not found in the map. Would you like to add it?"
°5u     getUserResponse1 :: IO (Maybe String)
°5u  f (Just old) -&gt; do
°5u     putStrLn "The key is currently bound to " ++ show old ++
°5u         ". Would you like to change or delete it?"
°5u     getUserresponse2 :: IO (Maybe String)
°5u</pre>
°5u
°5u<a>alterF</a> is the most general operation for working with an
°5uindividual key that may or may not be in a given map.
°5u
°5uNote: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
°5ufrom <a>At</a>.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | <i>O(n+m)</i>. The (left-biased) union of two maps. It prefers the
°5ufirst map when duplicate keys are encountered, i.e. (<tt><a>union</a>
°5u== <a>unionWith</a> <a>const</a></tt>).
°5u
°5u<pre>
°5uunion (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
°5u</pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5uunionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
°5u</pre>
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The union with a combining function.
°5u
°5u<pre>
°5ulet f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
°5uunionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
°5u</pre>
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
°5u
°5u<pre>
°5uunions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "b"), (5, "a"), (7, "C")]
°5uunions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
°5u    == fromList [(3, "B3"), (5, "A3"), (7, "C")]
°5u</pre>
unions :: [IntMap a] -> IntMap a

-- | The union of a list of maps, with a combining operation.
°5u
°5u<pre>
°5uunionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
°5u    == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
°5u</pre>
unionsWith :: (a -> a -> a) -> [IntMap a] -> IntMap a

-- | <i>O(n+m)</i>. Difference between two maps (based on keys).
°5u
°5u<pre>
°5udifference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
°5u</pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function.
°5u
°5u<pre>
°5ulet f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
°5udifferenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
°5u    == singleton 3 "b:B"
°5u</pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. Difference with a combining function. When two equal
°5ukeys are encountered, the combining function is applied to the key and
°5uboth values. If it returns <a>Nothing</a>, the element is discarded
°5u(proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
°5uelement is updated with a new value <tt>y</tt>.
°5u
°5u<pre>
°5ulet f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
°5udifferenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
°5u    == singleton 3 "3:b|B"
°5u</pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The (left-biased) intersection of two maps (based on
°5ukeys).
°5u
°5u<pre>
°5uintersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
°5u</pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5uintersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
°5u</pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n+m)</i>. The intersection with a combining function.
°5u
°5u<pre>
°5ulet f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
°5uintersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
°5u</pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n+m)</i>. A high-performance universal combining function. Using
°5u<a>mergeWithKey</a>, all combining functions can be defined without
°5uany loss of efficiency (with exception of <a>union</a>,
°5u<a>difference</a> and <a>intersection</a>, where sharing of some nodes
°5uis lost with <a>mergeWithKey</a>).
°5u
°5uPlease make sure you know what is going on when using
°5u<a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
°5ugrowth or even corruption of the data structure.
°5u
°5uWhen <a>mergeWithKey</a> is given three arguments, it is inlined to
°5uthe call site. You should therefore use <a>mergeWithKey</a> only to
°5udefine your custom combining functions. For example, you could define
°5u<a>unionWithKey</a>, <a>differenceWithKey</a> and
°5u<a>intersectionWithKey</a> as
°5u
°5u<pre>
°5umyUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
°5umyDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
°5umyIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
°5u</pre>
°5u
°5uWhen calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
°5ufunction combining two <a>IntMap</a>s is created, such that
°5u
°5u<ul>
°5u<li>if a key is present in both maps, it is passed with both
°5ucorresponding values to the <tt>combine</tt> function. Depending on
°5uthe result, the key is either present in the result with specified
°5uvalue, or is left out;</li>
°5u<li>a nonempty subtree present only in the first map is passed to
°5u<tt>only1</tt> and the output is added to the result;</li>
°5u<li>a nonempty subtree present only in the second map is passed to
°5u<tt>only2</tt> and the output is added to the result.</li>
°5u</ul>
°5u
°5uThe <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
°5uwith a subset (possibly empty) of the keys of the given map</i>. The
°5uvalues can be modified arbitrarily. Most common variants of
°5u<tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
°5u<a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
°5u<tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5umap (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
°5u</pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map a function over all values in the map.
°5u
°5u<pre>
°5ulet f key x = (show key) ++ ":" ++ x
°5umapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
°5u</pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
°5u<a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
°5u(<a>toList</a> m)</tt> That is, behaves exactly like a regular
°5u<a>traverse</a> except that the traversing function also has access to
°5uthe key associated with a value.
°5u
°5u<pre>
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
°5utraverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
°5u</pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | <i>O(n)</i>. The function <tt><a>mapAccum</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a b = (a ++ b, b ++ "X")
°5umapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><a>mapAccumWithKey</a></tt> threads an
°5uaccumulating argument through the map in ascending order of keys.
°5u
°5u<pre>
°5ulet f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
°5umapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
°5u</pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n)</i>. The function <tt><tt>mapAccumR</tt></tt> threads an
°5uaccumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeys</a> f s</tt> is the map obtained
°5uby applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the value at the
°5ugreatest of the original keys is retained.
°5u
°5u<pre>
°5umapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
°5umapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
°5umapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
°5u</pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeysWith</a> c f s</tt> is the map
°5uobtained by applying <tt>f</tt> to each key of <tt>s</tt>.
°5u
°5uThe size of the result may be smaller if <tt>f</tt> maps two or more
°5udistinct keys to the same new key. In this case the associated values
°5uwill be combined using <tt>c</tt>.
°5u
°5u<pre>
°5umapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
°5umapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
°5u</pre>
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <tt><a>mapKeysMonotonic</a> f s ==
°5u<a>mapKeys</a> f s</tt>, but works only when <tt>f</tt> is strictly
°5umonotonic. That is, for any values <tt>x</tt> and <tt>y</tt>, if
°5u<tt>x</tt> &lt; <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. <i>The
°5uprecondition is not checked.</i> Semi-formally, we have:
°5u
°5u<pre>
°5uand [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
°5u                    ==&gt; mapKeysMonotonic f s == mapKeys f s
°5u    where ls = keys s
°5u</pre>
°5u
°5uThis means that <tt>f</tt> maps distinct original keys to distinct
°5uresulting keys. This function has slightly better performance than
°5u<a>mapKeys</a>.
°5u
°5u<pre>
°5umapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
°5u</pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldr</a> f z ==
°5u<a>foldr</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems map = foldr (:) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f a len = len + (length a)
°5ufoldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldl</a> f z ==
°5u<a>foldl</a> f z . <a>elems</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5uelems = reverse . foldl (flip (:)) []
°5u</pre>
°5u
°5u<pre>
°5ulet f len a = len + (length a)
°5ufoldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
°5u</pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator, such that <tt><a>foldrWithKey</a> f
°5uz == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
°5u</pre>
°5u
°5u<pre>
°5ulet f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
°5u</pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uleft-associative binary operator, such that <tt><a>foldlWithKey</a> f
°5uz == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
°5u<a>toAscList</a></tt>.
°5u
°5uFor example,
°5u
°5u<pre>
°5ukeys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
°5u</pre>
°5u
°5u<pre>
°5ulet f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
°5ufoldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
°5u</pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5umonoid, such that
°5u
°5u<pre>
°5u<a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
°5u</pre>
°5u
°5uThis can be an asymptotically faster than <a>foldrWithKey</a> or
°5u<a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | <i>O(n)</i>. A strict version of <a>foldr</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldl</a>. Each application of the
°5uoperator is evaluated before using the result in the next application.
°5uThis function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. A strict version of <a>foldrWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. A strict version of <a>foldlWithKey</a>. Each application
°5uof the operator is evaluated before using the result in the next
°5uapplication. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | <i>O(n)</i>. Return all elements of the map in the ascending order of
°5utheir keys. Subject to list fusion.
°5u
°5u<pre>
°5uelems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
°5uelems empty == []
°5u</pre>
elems :: IntMap a -> [a]

-- | <i>O(n)</i>. Return all keys of the map in ascending order. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5ukeys (fromList [(5,"a"), (3,"b")]) == [3,5]
°5ukeys empty == []
°5u</pre>
keys :: IntMap a -> [Key]

-- | <i>O(n)</i>. An alias for <a>toAscList</a>. Returns all key/value
°5upairs in the map in ascending key order. Subject to list fusion.
°5u
°5u<pre>
°5uassocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5uassocs empty == []
°5u</pre>
assocs :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. The set of all keys of the map.
°5u
°5u<pre>
°5ukeysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
°5ukeysSet empty == Data.IntSet.empty
°5u</pre>
keysSet :: IntMap a -> IntSet

-- | <i>O(n)</i>. Build a map from a set of keys and a function which for
°5ueach key computes its value.
°5u
°5u<pre>
°5ufromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
°5ufromSet undefined Data.IntSet.empty == empty
°5u</pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs. Subject to
°5ulist fusion.
°5u
°5u<pre>
°5utoList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5utoList empty == []
°5u</pre>
toList :: IntMap a -> [(Key, a)]

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs.
°5u
°5u<pre>
°5ufromList [] == empty
°5ufromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
°5ufromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
°5u</pre>
fromList :: [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Create a map from a list of key/value pairs with
°5ua combining function. See also <a>fromAscListWith</a>.
°5u
°5u<pre>
°5ufromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "ab"), (5, "cba")]
°5ufromListWith (++) [] == empty
°5u</pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Build a map from a list of key/value pairs with
°5ua combining function. See also fromAscListWithKey'.
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5ufromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
°5ufromListWithKey f [] == empty
°5u</pre>
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in ascending order. Subject to list fusion.
°5u
°5u<pre>
°5utoAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
°5u</pre>
toAscList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Convert the map to a list of key/value pairs where the
°5ukeys are in descending order. Subject to list fusion.
°5u
°5u<pre>
°5utoDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
°5u</pre>
toDescList :: IntMap a -> [(Key, a)]

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order.
°5u
°5u<pre>
°5ufromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
°5ufromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
°5u</pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
°5u</pre>
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order, with a combining function on equal keys.
°5u<i>The precondition (input list is ascending) is not checked.</i>
°5u
°5u<pre>
°5ulet f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
°5ufromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]
°5u</pre>
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
°5uare in ascending order and all distinct. <i>The precondition (input
°5ulist is strictly ascending) is not checked.</i>
°5u
°5u<pre>
°5ufromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
°5u</pre>
fromDistinctAscList :: forall a. [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Filter all values that satisfy some predicate.
°5u
°5u<pre>
°5ufilter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5ufilter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
°5ufilter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
°5u</pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Filter all keys/values that satisfy some predicate.
°5u
°5u<pre>
°5ufilterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. The restriction of a map to the keys in a set.
°5u
°5u<pre>
°5um <a>restrictKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>member'</a> s) m
°5u</pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n+m)</i>. Remove all the keys in a given set from a map.
°5u
°5u<pre>
°5um <a>withoutKeys</a> s = <a>filterWithKey</a> (k _ -&gt; k `<a>notMember'</a> s) m
°5u</pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5upartition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Partition the map according to some predicate. The first
°5umap contains all elements that satisfy the predicate, the second all
°5uelements that fail the predicate. See also <a>split</a>.
°5u
°5u<pre>
°5upartitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
°5upartitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
°5upartitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
°5u</pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(n)</i>. Map values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f x = if x == "a" then Just "new a" else Nothing
°5umapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
°5u</pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map keys/values and collect the <a>Just</a> results.
°5u
°5u<pre>
°5ulet f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
°5umapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
°5u</pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | <i>O(n)</i>. Map values and separate the <a>Left</a> and <a>Right</a>
°5uresults.
°5u
°5u<pre>
°5ulet f a = if a &lt; "c" then Left a else Right a
°5umapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
°5u
°5umapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u</pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(n)</i>. Map keys/values and separate the <a>Left</a> and
°5u<a>Right</a> results.
°5u
°5u<pre>
°5ulet f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
°5umapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
°5u
°5umapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
°5u    == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
°5u</pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | <i>O(min(n,W))</i>. The expression (<tt><a>split</a> k map</tt>) is a
°5upair <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower
°5uthan <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>.
°5uAny key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
°5u<tt>map2</tt>.
°5u
°5u<pre>
°5usplit 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
°5usplit 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
°5usplit 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
°5usplit 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
°5usplit 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
°5u</pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
°5uthe pivot key was found in the original map.
°5u
°5u<pre>
°5usplitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
°5usplitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
°5usplitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
°5usplitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
°5usplitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
°5u</pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | <i>O(1)</i>. Decompose a map into pieces based on the structure of the
°5uunderlying tree. This function is useful for consuming a map in
°5uparallel.
°5u
°5uNo guarantee is made as to the sizes of the pieces; an internal, but
°5udeterministic process determines this. However, it is guaranteed that
°5uthe pieces returned will be in ascending order (all elements in the
°5ufirst submap less than all elements in the second, and so on).
°5u
°5uExamples:
°5u
°5u<pre>
°5usplitRoot (fromList (zip [1..6::Int] ['a'..])) ==
°5u  [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
°5u</pre>
°5u
°5u<pre>
°5usplitRoot empty == []
°5u</pre>
°5u
°5uNote that the current implementation does not return more than two
°5usubmaps, but you should not depend on this behaviour because it can
°5uchange in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | <i>O(n+m)</i>. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
°5u<a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
°5ureturns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
°5uwhen <tt>f</tt> returns <a>True</a> when applied to their respective
°5uvalues. For example, the following expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5u</pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uDefined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
°5u(==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. Is this a proper submap? (ie. a submap but not equal).
°5uThe expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
°5u<a>True</a> when <tt>m1</tt> and <tt>m2</tt> are not equal, all keys
°5uin <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt> returns
°5u<a>True</a> when applied to their respective values. For example, the
°5ufollowing expressions are all <a>True</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
°5u</pre>
°5u
°5uBut the following are all <a>False</a>:
°5u
°5u<pre>
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
°5uisProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
°5uisProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
°5u</pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | <i>O(min(n,W))</i>. The minimal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Returns <a>Nothing</a>
°5uif the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | <i>O(min(n,W))</i>. The minimal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>minViewWithKey</a> if the map may be empty.
findMin :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map. Calls <a>error</a> if
°5uthe map is empty. Use <a>maxViewWithKey</a> if the map may be empty.
findMax :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. Delete the minimal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMin :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete the maximal key. Returns an empty map if
°5uthe map is empty.
°5u
°5uNote that this is a change of behaviour for consistency with
°5u<a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
°5uwas already empty.
deleteMax :: IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Delete and find the minimal element. This function
°5uthrows an error if the map is empty. Use <a>minViewWithKey</a> if the
°5umap may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element. This function
°5uthrows an error if the map is empty. Use <a>maxViewWithKey</a> if the
°5umap may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
°5uupdateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
°5uupdateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the minimal key.
°5u
°5u<pre>
°5uupdateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
°5uupdateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
°5u</pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Update the value at the maximal key.
°5u
°5u<pre>
°5uupdateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
°5uupdateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
°5u</pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. Retrieves the minimal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal key of the map, and the map
°5ustripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the minimal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5uminViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
°5uminViewWithKey empty == Nothing
°5u</pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Retrieves the maximal (key,value) pair of the map,
°5uand the map stripped of that element, or <a>Nothing</a> if passed an
°5uempty map.
°5u
°5u<pre>
°5umaxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
°5umaxViewWithKey empty == Nothing
°5u</pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format.

-- | <i>Deprecated: These debugging functions will be removed from this
°5umodule. They are available from Data.IntMap.Internal.Debug.</i>
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the map. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.

-- | <i>Deprecated: These debugging functions will be removed from this
°5umodule. They are available from Data.IntMap.Internal.Debug.</i>
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String


-- | An efficient implementation of maps from integer keys to values
°5u(dictionaries).
°5u
°5uThis module re-exports the value lazy <a>Data.IntMap.Lazy</a> API,
°5uplus several deprecated value strict functions. Please note that these
°5ufunctions have different strictness properties than those in
°5u<a>Data.IntMap.Strict</a>: they only evaluate the result of the
°5ucombining function. For example, the default value to
°5u<a>insertWith'</a> is only evaluated if the combining function is
°5ucalled and uses it.
°5u
°5uThese modules are intended to be imported qualified, to avoid name
°5uclashes with Prelude functions, e.g.
°5u
°5u<pre>
°5uimport Data.IntMap (IntMap)
°5uimport qualified Data.IntMap as IntMap
°5u</pre>
°5u
°5uThe implementation is based on <i>big-endian patricia trees</i>. This
°5udata structure performs especially well on binary operations like
°5u<a>union</a> and <a>intersection</a>. However, my benchmarks show that
°5uit is also (much) faster on insertions and deletions when compared to
°5ua generic size-balanced map implementation (see <a>Data.Map</a>).
°5u
°5u<ul>
°5u<li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
°5uWorkshop on ML, September 1998, pages 77-86,
°5u<a>http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452</a></li>
°5u<li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
°5uInformation Coded In Alphanumeric/", Journal of the ACM, 15(4),
°5uOctober 1968, pages 514-534.</li>
°5u</ul>
°5u
°5uOperation comments contain the operation time complexity in the Big-O
°5unotation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
°5uoperations have a worst-case complexity of <i>O(min(n,W))</i>. This
°5umeans that the operation can become linear in the number of elements
°5uwith a maximum of <i>W</i> -- the number of bits in an <tt>Int</tt>
°5u(32 or 64).
module Data.IntMap

-- | <i>O(log n)</i>. Same as <a>insertWith</a>, but the result of the
°5ucombining function is evaluated to WHNF before inserted to the map.

-- | <i>Deprecated: As of version 0.5, replaced by <a>insertWith</a>.</i>
insertWith' :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(log n)</i>. Same as <a>insertWithKey</a>, but the result of the
°5ucombining function is evaluated to WHNF before inserted to the map.

-- | <i>Deprecated: As of version 0.5, replaced by
°5u<a>insertWithKey</a>.</i>
insertWithKey' :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(n)</i>. Fold the values in the map using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldr</a> and is present for compatibility only.

-- | <i>Deprecated: As of version 0.5, replaced by <a>foldr</a>.</i>
fold :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>O(n)</i>. Fold the keys and values in the map using the given
°5uright-associative binary operator. This function is an equivalent of
°5u<a>foldrWithKey</a> and is present for compatibility only.

-- | <i>Deprecated: As of version 0.5, replaced by <a>foldrWithKey</a>.</i>
foldWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

module Data.IntMap.Internal.Debug

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
°5uin a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. The expression (<tt><a>showTreeWith</a> hang wide
°5umap</tt>) shows the tree that implements the map. If <tt>hang</tt> is
°5u<a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
°5uis shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
°5ushown.
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String
