    {-# LANGUAGE CPP #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE PatternGuards #-}
    #if __GLASGOW_HASKELL__
    {-# LANGUAGE MagicHash, DeriveDataTypeable, StandaloneDeriving #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    #endif
    #if !defined(TESTING) && defined(__GLASGOW_HASKELL__)
    {-# LANGUAGE Trustworthy #-}
    #endif
    #if __GLASGOW_HASKELL__ >= 708
    {-# LANGUAGE TypeFamilies #-}
    #endif

    {-# OPTIONS_HADDOCK not-home #-}
    {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}

    #include "containers.h"

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.IntMap.Internal
    -- Copyright   :  (c) Daan Leijen 2002
    --                (c) Andriy Palamarchuk 2008
    --                (c) wren romano 2016
    -- License     :  BSD-style
    -- Maintainer  :  libraries@haskell.org
    -- Portability :  portable
    --
    -- = WARNING
    --
    -- This module is considered __internal__.
    --
    -- The Package Versioning Policy __does not apply__.
    --
    -- The contents of this module may change __in any way whatsoever__
    -- and __without any warning__ between minor versions of this package.
    --
    -- Authors importing this module are expected to track development
    -- closely.
    --
    -- = Description
    --
    -- This defines the data structures and core (hidden) manipulations
    -- on representations.
    --
    -- @since 0.5.9
    -----------------------------------------------------------------------------

    -- [Note: INLINE bit fiddling]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- It is essential that the bit fiddling functions like mask, zero, branchMask
    -- etc are inlined. If they do not, the memory allocation skyrockets. The GHC
    -- usually gets it right, but it is disastrous if it does not. Therefore we
    -- explicitly mark these functions INLINE.

    -- [Note: Local 'go' functions and capturing]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- Care must be taken when using 'go' function which captures an argument.
    -- Sometimes (for example when the argument is passed to a data constructor,
    -- as in insert), GHC heap-allocates more than necessary. Therefore C-- code
    -- must be checked for increased allocation when creating and modifying such
    -- functions.

    -- [Note: Order of constructors]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- The order of constructors of IntMap matters when considering performance.
    -- Currently in GHC 7.0, when type has 3 constructors, they are matched from
    -- the first to the last -- the best performance is achieved when the
    -- constructors are ordered by frequency.
    -- On GHC 7.0, reordering constructors from Nil | Tip | Bin to Bin | Tip | Nil
    -- improves the benchmark by circa 10%.

    module Data.IntMap.Internal (
        -- * Map type
          IntMap(..), Key          -- instance Eq,Show

        -- * Operators
        , (!), (!?), (\\)

        -- * Query
        , null
        , size
        , member
        , notMember
        , lookup
        , findWithDefault
        , lookupLT
        , lookupGT
        , lookupLE
        , lookupGE
        , disjoint

        -- * Construction
        , empty
        , singleton

        -- ** Insertion
        , insert
        , insertWith
        , insertWithKey
        , insertLookupWithKey

        -- ** Delete\/Update
        , delete
        , adjust
        , adjustWithKey
        , update
        , updateWithKey
        , updateLookupWithKey
        , alter
        , alterF

        -- * Combine

        -- ** Union
        , union
        , unionWith
        , unionWithKey
        , unions
        , unionsWith

        -- ** Difference
        , difference
        , differenceWith
        , differenceWithKey

        -- ** Intersection
        , intersection
        , intersectionWith
        , intersectionWithKey

        -- ** Compose
        , compose

        -- ** General combining function
        , SimpleWhenMissing
        , SimpleWhenMatched
        , runWhenMatched
        , runWhenMissing
        , merge
        -- *** @WhenMatched@ tactics
        , zipWithMaybeMatched
        , zipWithMatched
        -- *** @WhenMissing@ tactics
        , mapMaybeMissing
        , dropMissing
        , preserveMissing
        , mapMissing
        , filterMissing

        -- ** Applicative general combining function
        , WhenMissing (..)
        , WhenMatched (..)
        , mergeA
        -- *** @WhenMatched@ tactics
        -- | The tactics described for 'merge' work for
        -- 'mergeA' as well. Furthermore, the following
        -- are available.
        , zipWithMaybeAMatched
        , zipWithAMatched
        -- *** @WhenMissing@ tactics
        -- | The tactics described for 'merge' work for
        -- 'mergeA' as well. Furthermore, the following
        -- are available.
        , traverseMaybeMissing
        , traverseMissing
        , filterAMissing

        -- ** Deprecated general combining function
        , mergeWithKey
        , mergeWithKey'

        -- * Traversal
        -- ** Map
        , map
        , mapWithKey
        , traverseWithKey
        , traverseMaybeWithKey
        , mapAccum
        , mapAccumWithKey
        , mapAccumRWithKey
        , mapKeys
        , mapKeysWith
        , mapKeysMonotonic

        -- * Folds
        , foldr
        , foldl
        , foldrWithKey
        , foldlWithKey
        , foldMapWithKey

        -- ** Strict folds
        , foldr'
        , foldl'
        , foldrWithKey'
        , foldlWithKey'

        -- * Conversion
        , elems
        , keys
        , assocs
        , keysSet
        , fromSet

        -- ** Lists
        , toList
        , fromList
        , fromListWith
        , fromListWithKey

        -- ** Ordered lists
        , toAscList
        , toDescList
        , fromAscList
        , fromAscListWith
        , fromAscListWithKey
        , fromDistinctAscList

        -- * Filter
        , filter
        , filterWithKey
        , restrictKeys
        , withoutKeys
        , partition
        , partitionWithKey

        , mapMaybe
        , mapMaybeWithKey
        , mapEither
        , mapEitherWithKey

        , split
        , splitLookup
        , splitRoot

        -- * Submap
        , isSubmapOf, isSubmapOfBy
        , isProperSubmapOf, isProperSubmapOfBy

        -- * Min\/Max
        , lookupMin
        , lookupMax
        , findMin
        , findMax
        , deleteMin
        , deleteMax
        , deleteFindMin
        , deleteFindMax
        , updateMin
        , updateMax
        , updateMinWithKey
        , updateMaxWithKey
        , minView
        , maxView
        , minViewWithKey
        , maxViewWithKey

        -- * Debugging
        , showTree
        , showTreeWith

        -- * Internal types
        , Mask, Prefix, Nat

        -- * Utility
        , natFromInt
        , intFromNat
        , link
        , linkWithMask
        , bin
        , binCheckLeft
        , binCheckRight
        , zero
        , nomatch
        , match
        , mask
        , maskW
        , shorter
        , branchMask
        , highestBitMask

        -- * Used by "IntMap.Merge.Lazy" and "IntMap.Merge.Strict"
        , mapWhenMissing
        , mapWhenMatched
        , lmapWhenMissing
        , contramapFirstWhenMatched
        , contramapSecondWhenMatched
        , mapGentlyWhenMissing
        , mapGentlyWhenMatched
        ) where

    #if MIN_VERSION_base(4,8,0)
    import Data.Functor.Identity (Identity (..))
    import Control.Applicative (liftA2)
    #else
    import Control.Applicative (Applicative(pure, (<*>)), (<$>), liftA2)
    import Data.Monoid (Monoid(..))
    import Data.Traversable (Traversable(traverse))
    import Data.Word (Word)
    #endif
    #if MIN_VERSION_base(4,9,0)
    import Data.Semigroup (Semigroup(stimes))
    #endif
    #if !(MIN_VERSION_base(4,11,0)) && MIN_VERSION_base(4,9,0)
    import Data.Semigroup (Semigroup((<>)))
    #endif
    #if MIN_VERSION_base(4,9,0)
    import Data.Semigroup (stimesIdempotentMonoid)
    import Data.Functor.Classes
    #endif

    import Control.DeepSeq (NFData(rnf))
    import Data.Bits
    import qualified Data.Foldable as Foldable
    #if !MIN_VERSION_base(4,8,0)
    import Data.Foldable (Foldable())
    #endif
    import Data.Maybe (fromMaybe)
    import Data.Typeable
    import Prelude hiding (lookup, map, filter, foldr, foldl, null)

    import Data.IntSet.Internal (Key)
    import qualified Data.IntSet.Internal as IntSet
    import Utils.Containers.Internal.BitUtil
    import Utils.Containers.Internal.StrictPair

    #if __GLASGOW_HASKELL__
    import Data.Data (Data(..), Constr, mkConstr, constrIndex, Fixity(Prefix),
                      DataType, mkDataType)
    import GHC.Exts (build)
    #if !MIN_VERSION_base(4,8,0)
    import Data.Functor ((<$))
    #endif
    #if __GLASGOW_HASKELL__ >= 708
    import qualified GHC.Exts as GHCExts
    #endif
    import Text.Read
    #endif
    import qualified Control.Category as Category
    #if __GLASGOW_HASKELL__ >= 709
    import Data.Coerce
    #endif

    -- A "Nat" is a natural machine word (an unsigned Int)
    type Nat = Word

    natFromInt :: Key -> Nat
    natFromInt :: Int -> Nat
    natFromInt = forall a b. (Integral a, Num b) => a -> b
    fromIntegral
    {-# INLINE natFromInt #-}

    intFromNat :: Nat -> Key
    intFromNat :: Nat -> Int
    intFromNat = forall a b. (Integral a, Num b) => a -> b
    fromIntegral
    {-# INLINE intFromNat #-}

    {--------------------------------------------------------------------
      Types
    --------------------------------------------------------------------}

    -- | A map of integers to values @a@.

    -- See Note: Order of constructors
    data IntMap a = Bin {-# UNPACK #-} !Prefix
                        {-# UNPACK #-} !Mask
                        !(IntMap a)
                        !(IntMap a)
    -- Fields:
    --   prefix: The most significant bits shared by all keys in this Bin.
    --   mask: The switching bit to determine if a key should follow the left
    --         or right subtree of a 'Bin'.
    -- Invariant: Nil is never found as a child of Bin.
    -- Invariant: The Mask is a power of 2. It is the largest bit position at which
    --            two keys of the map differ.
    -- Invariant: Prefix is the common high-order bits that all elements share to
    --            the left of the Mask bit.
    -- Invariant: In (Bin prefix mask left right), left consists of the elements that
    --            don't have the mask bit set; right is all the elements that do.
                  | Tip {-# UNPACK #-} !Key a
                  | Nil

    type Prefix = Int
    type Mask   = Int

    -- Some stuff from "Data.IntSet.Internal", for 'restrictKeys' and
    -- 'withoutKeys' to use.
    type IntSetPrefix = Int
    type IntSetBitMap = Word

    bitmapOf :: Int -> IntSetBitMap
    bitmapOf :: Int -> Nat
    bitmapOf Int
    x = Nat -> Int -> Nat
    shiftLL Nat
    1 (Int
    x forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.suffixBitMask)
    {-# INLINE bitmapOf #-}

    {--------------------------------------------------------------------
      Operators
    --------------------------------------------------------------------}

    -- | /O(min(n,W))/. Find the value at a key.
    -- Calls 'error' when the element can not be found.
    --
    -- > fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
    -- > fromList [(5,'a'), (3,'b')] ! 5 == 'a'

    (!) :: IntMap a -> Key -> a
    ! :: forall a. IntMap a -> Int -> a
    (!) IntMap a
    m Int
    k = forall a. Int -> IntMap a -> a
    find Int
    k IntMap a
    m

    -- | /O(min(n,W))/. Find the value at a key.
    -- Returns 'Nothing' when the element can not be found.
    --
    -- > fromList [(5,'a'), (3,'b')] !? 1 == Nothing
    -- > fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
    --
    -- @since 0.5.11

    (!?) :: IntMap a -> Key -> Maybe a
    !? :: forall a. IntMap a -> Int -> Maybe a
    (!?) IntMap a
    m Int
    k = forall a. Int -> IntMap a -> Maybe a
    lookup Int
    k IntMap a
    m

    -- | Same as 'difference'.
    (\\) :: IntMap a -> IntMap b -> IntMap a
    IntMap a
    m1 \\ :: forall a b. IntMap a -> IntMap b -> IntMap a
    \\ IntMap b
    m2 = forall a b. IntMap a -> IntMap b -> IntMap a
    difference IntMap a
    m1 IntMap b
    m2

    infixl 9 !?,\\{-This comment teaches CPP correct behaviour -}

    {--------------------------------------------------------------------
      Types
    --------------------------------------------------------------------}

    instance Monoid (IntMap a) where
        mempty :: IntMap a
    mempty  = forall a. IntMap a
    empty
        mconcat :: [IntMap a] -> IntMap a
    mconcat = forall (f :: * -> *) a. Foldable f => f (IntMap a) -> IntMap a
    unions
    #if !(MIN_VERSION_base(4,9,0))
        mappend = union
    #else
        mappend :: IntMap a -> IntMap a -> IntMap a
    mappend = forall a. Semigroup a => a -> a -> a
    (<>)

    -- | @since 0.5.7
    instance Semigroup (IntMap a) where
        <> :: IntMap a -> IntMap a -> IntMap a
    (<>)    = forall a. IntMap a -> IntMap a -> IntMap a
    union
        stimes :: forall b. Integral b => b -> IntMap a -> IntMap a
    stimes  = forall b a. (Integral b, Monoid a) => b -> a -> a
    stimesIdempotentMonoid
    #endif

    -- | Folds in order of increasing key.
    instance Foldable.Foldable IntMap where
      fold :: forall m. Monoid m => IntMap m -> m
    fold = forall m. Monoid m => IntMap m -> m
    go
        where go :: IntMap a -> a
    go IntMap a
    Nil = forall a. Monoid a => a
    mempty
              go (Tip Int
    _ a
    v) = a
    v
              go (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
                | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = IntMap a -> a
    go IntMap a
    r forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> a
    go IntMap a
    l
                | Bool
    otherwise = IntMap a -> a
    go IntMap a
    l forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> a
    go IntMap a
    r
      {-# INLINABLE fold #-}
      foldr :: forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr = forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr
      {-# INLINE foldr #-}
      foldl :: forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl = forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl
      {-# INLINE foldl #-}
      foldMap :: forall m a. Monoid m => (a -> m) -> IntMap a -> m
    foldMap a -> m
    f IntMap a
    t = IntMap a -> m
    go IntMap a
    t
        where go :: IntMap a -> m
    go IntMap a
    Nil = forall a. Monoid a => a
    mempty
              go (Tip Int
    _ a
    v) = a -> m
    f a
    v
              go (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
                | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = IntMap a -> m
    go IntMap a
    r forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> m
    go IntMap a
    l
                | Bool
    otherwise = IntMap a -> m
    go IntMap a
    l forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> m
    go IntMap a
    r
      {-# INLINE foldMap #-}
      foldl' :: forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl' = forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl'
      {-# INLINE foldl' #-}
      foldr' :: forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr' = forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr'
      {-# INLINE foldr' #-}
    #if MIN_VERSION_base(4,8,0)
      length :: forall a. IntMap a -> Int
    length = forall a. IntMap a -> Int
    size
      {-# INLINE length #-}
      null :: forall a. IntMap a -> Bool
    null   = forall a. IntMap a -> Bool
    null
      {-# INLINE null #-}
      toList :: forall a. IntMap a -> [a]
    toList = forall a. IntMap a -> [a]
    elems -- NB: Foldable.toList /= IntMap.toList
      {-# INLINE toList #-}
      elem :: forall a. Eq a => a -> IntMap a -> Bool
    elem = forall a. Eq a => a -> IntMap a -> Bool
    go
        where go :: t -> IntMap t -> Bool
    go !t
    _ IntMap t
    Nil = Bool
    False
              go t
    x (Tip Int
    _ t
    y) = t
    x forall a. Eq a => a -> a -> Bool
    == t
    y
              go t
    x (Bin Int
    _ Int
    _ IntMap t
    l IntMap t
    r) = t -> IntMap t -> Bool
    go t
    x IntMap t
    l Bool -> Bool -> Bool
    || t -> IntMap t -> Bool
    go t
    x IntMap t
    r
      {-# INLINABLE elem #-}
      maximum :: forall a. Ord a => IntMap a -> a
    maximum = forall a. Ord a => IntMap a -> a
    start
        where start :: IntMap a -> a
    start IntMap a
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.Foldable.maximum (for Data.IntMap): empty map"
              start (Tip Int
    _ a
    y) = a
    y
              start (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
                | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall {t}. Ord t => t -> IntMap t -> t
    go (IntMap a -> a
    start IntMap a
    r) IntMap a
    l
                | Bool
    otherwise = forall {t}. Ord t => t -> IntMap t -> t
    go (IntMap a -> a
    start IntMap a
    l) IntMap a
    r

              go :: t -> IntMap t -> t
    go !t
    m IntMap t
    Nil = t
    m
              go t
    m (Tip Int
    _ t
    y) = forall a. Ord a => a -> a -> a
    max t
    m t
    y
              go t
    m (Bin Int
    _ Int
    _ IntMap t
    l IntMap t
    r) = t -> IntMap t -> t
    go (t -> IntMap t -> t
    go t
    m IntMap t
    l) IntMap t
    r
      {-# INLINABLE maximum #-}
      minimum :: forall a. Ord a => IntMap a -> a
    minimum = forall a. Ord a => IntMap a -> a
    start
        where start :: IntMap a -> a
    start IntMap a
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.Foldable.minimum (for Data.IntMap): empty map"
              start (Tip Int
    _ a
    y) = a
    y
              start (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
                | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall {t}. Ord t => t -> IntMap t -> t
    go (IntMap a -> a
    start IntMap a
    r) IntMap a
    l
                | Bool
    otherwise = forall {t}. Ord t => t -> IntMap t -> t
    go (IntMap a -> a
    start IntMap a
    l) IntMap a
    r

              go :: t -> IntMap t -> t
    go !t
    m IntMap t
    Nil = t
    m
              go t
    m (Tip Int
    _ t
    y) = forall a. Ord a => a -> a -> a
    min t
    m t
    y
              go t
    m (Bin Int
    _ Int
    _ IntMap t
    l IntMap t
    r) = t -> IntMap t -> t
    go (t -> IntMap t -> t
    go t
    m IntMap t
    l) IntMap t
    r
      {-# INLINABLE minimum #-}
      sum :: forall a. Num a => IntMap a -> a
    sum = forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl' forall a. Num a => a -> a -> a
    (+) a
    0
      {-# INLINABLE sum #-}
      product :: forall a. Num a => IntMap a -> a
    product = forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl' forall a. Num a => a -> a -> a
    (*) a
    1
      {-# INLINABLE product #-}
    #endif

    -- | Traverses in order of increasing key.
    instance Traversable IntMap where
        traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> IntMap a -> f (IntMap b)
    traverse a -> f b
    f = forall (t :: * -> *) a b.
    Applicative t =>
    (Int -> a -> t b) -> IntMap a -> t (IntMap b)
    traverseWithKey (\Int
    _ -> a -> f b
    f)
        {-# INLINE traverse #-}

    instance NFData a => NFData (IntMap a) where
        rnf :: IntMap a -> ()
    rnf IntMap a
    Nil = ()
        rnf (Tip Int
    _ a
    v) = forall a. NFData a => a -> ()
    rnf a
    v
        rnf (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = forall a. NFData a => a -> ()
    rnf IntMap a
    l seq :: forall a b. a -> b -> b
    `seq` forall a. NFData a => a -> ()
    rnf IntMap a
    r

    #if __GLASGOW_HASKELL__

    {--------------------------------------------------------------------
      A Data instance
    --------------------------------------------------------------------}

    -- This instance preserves data abstraction at the cost of inefficiency.
    -- We provide limited reflection services for the sake of data abstraction.

    instance Data a => Data (IntMap a) where
      gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> IntMap a -> c (IntMap a)
    gfoldl forall d b. Data d => c (d -> b) -> d -> c b
    f forall g. g -> c g
    z IntMap a
    im = forall g. g -> c g
    z forall a. [(Int, a)] -> IntMap a
    fromList forall d b. Data d => c (d -> b) -> d -> c b
    `f` (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    im)
      toConstr :: IntMap a -> Constr
    toConstr IntMap a
    _     = Constr
    fromListConstr
      gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (IntMap a)
    gunfold forall b r. Data b => c (b -> r) -> c r
    k forall r. r -> c r
    z Constr
    c  = case Constr -> Int
    constrIndex Constr
    c of
        Int
    1 -> forall b r. Data b => c (b -> r) -> c r
    k (forall r. r -> c r
    z forall a. [(Int, a)] -> IntMap a
    fromList)
        Int
    _ -> forall a. HasCallStack => [Char] -> a
    error [Char]
    "gunfold"
      dataTypeOf :: IntMap a -> DataType
    dataTypeOf IntMap a
    _   = DataType
    intMapDataType
      dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (IntMap a))
    dataCast1 forall d. Data d => c (t d)
    f    = forall {k1} {k2} (c :: k1 -> *) (t :: k2 -> k1) (t' :: k2 -> k1)
           (a :: k2).
    (Typeable t, Typeable t') =>
    c (t a) -> Maybe (c (t' a))
    gcast1 forall d. Data d => c (t d)
    f

    fromListConstr :: Constr
    fromListConstr :: Constr
    fromListConstr = DataType -> [Char] -> [[Char]] -> Fixity -> Constr
    mkConstr DataType
    intMapDataType [Char]
    "fromList" [] Fixity
    Prefix

    intMapDataType :: DataType
    intMapDataType :: DataType
    intMapDataType = [Char] -> [Constr] -> DataType
    mkDataType [Char]
    "Data.IntMap.Internal.IntMap" [Constr
    fromListConstr]

    #endif

    {--------------------------------------------------------------------
      Query
    --------------------------------------------------------------------}
    -- | /O(1)/. Is the map empty?
    --
    -- > Data.IntMap.null (empty)           == True
    -- > Data.IntMap.null (singleton 1 'a') == False

    null :: IntMap a -> Bool
    null :: forall a. IntMap a -> Bool
    null IntMap a
    Nil = Bool
    True
    null IntMap a
    _   = Bool
    False
    {-# INLINE null #-}

    -- | /O(n)/. Number of elements in the map.
    --
    -- > size empty                                   == 0
    -- > size (singleton 1 'a')                       == 1
    -- > size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
    size :: IntMap a -> Int
    size :: forall a. IntMap a -> Int
    size = forall {t} {a}. Num t => t -> IntMap a -> t
    go Int
    0
      where
        go :: t -> IntMap a -> t
    go !t
    acc (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = t -> IntMap a -> t
    go (t -> IntMap a -> t
    go t
    acc IntMap a
    l) IntMap a
    r
        go t
    acc (Tip Int
    _ a
    _) = t
    1 forall a. Num a => a -> a -> a
    + t
    acc
        go t
    acc IntMap a
    Nil = t
    acc

    -- | /O(min(n,W))/. Is the key a member of the map?
    --
    -- > member 5 (fromList [(5,'a'), (3,'b')]) == True
    -- > member 1 (fromList [(5,'a'), (3,'b')]) == False

    -- See Note: Local 'go' functions and capturing]
    member :: Key -> IntMap a -> Bool
    member :: forall a. Int -> IntMap a -> Bool
    member !Int
    k = IntMap a -> Bool
    go
      where
        go :: IntMap a -> Bool
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = Bool
    False
                         | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> Bool
    go IntMap a
    l
                         | Bool
    otherwise = IntMap a -> Bool
    go IntMap a
    r
        go (Tip Int
    kx a
    _) = Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    kx
        go IntMap a
    Nil = Bool
    False

    -- | /O(min(n,W))/. Is the key not a member of the map?
    --
    -- > notMember 5 (fromList [(5,'a'), (3,'b')]) == False
    -- > notMember 1 (fromList [(5,'a'), (3,'b')]) == True

    notMember :: Key -> IntMap a -> Bool
    notMember :: forall a. Int -> IntMap a -> Bool
    notMember Int
    k IntMap a
    m = Bool -> Bool
    not forall a b. (a -> b) -> a -> b
    $ forall a. Int -> IntMap a -> Bool
    member Int
    k IntMap a
    m

    -- | /O(min(n,W))/. Lookup the value at a key in the map. See also 'Data.Map.lookup'.

    -- See Note: Local 'go' functions and capturing]
    lookup :: Key -> IntMap a -> Maybe a
    lookup :: forall a. Int -> IntMap a -> Maybe a
    lookup !Int
    k = IntMap a -> Maybe a
    go
      where
        go :: IntMap a -> Maybe a
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = forall a. Maybe a
    Nothing
                         | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> Maybe a
    go IntMap a
    l
                         | Bool
    otherwise = IntMap a -> Maybe a
    go IntMap a
    r
        go (Tip Int
    kx a
    x) | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    kx   = forall a. a -> Maybe a
    Just a
    x
                      | Bool
    otherwise = forall a. Maybe a
    Nothing
        go IntMap a
    Nil = forall a. Maybe a
    Nothing

    -- See Note: Local 'go' functions and capturing]
    find :: Key -> IntMap a -> a
    find :: forall a. Int -> IntMap a -> a
    find !Int
    k = IntMap a -> a
    go
      where
        go :: IntMap a -> a
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = a
    not_found
                         | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> a
    go IntMap a
    l
                         | Bool
    otherwise = IntMap a -> a
    go IntMap a
    r
        go (Tip Int
    kx a
    x) | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    kx   = a
    x
                      | Bool
    otherwise = a
    not_found
        go IntMap a
    Nil = a
    not_found

        not_found :: a
    not_found = forall a. HasCallStack => [Char] -> a
    error ([Char]
    "IntMap.!: key " forall a. [a] -> [a] -> [a]
    ++ forall a. Show a => a -> [Char]
    show Int
    k forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is not an element of the map")

    -- | /O(min(n,W))/. The expression @('findWithDefault' def k map)@
    -- returns the value at key @k@ or returns @def@ when the key is not an
    -- element of the map.
    --
    -- > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
    -- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'

    -- See Note: Local 'go' functions and capturing]
    findWithDefault :: a -> Key -> IntMap a -> a
    findWithDefault :: forall a. a -> Int -> IntMap a -> a
    findWithDefault a
    def !Int
    k = IntMap a -> a
    go
      where
        go :: IntMap a -> a
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = a
    def
                         | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> a
    go IntMap a
    l
                         | Bool
    otherwise = IntMap a -> a
    go IntMap a
    r
        go (Tip Int
    kx a
    x) | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    kx   = a
    x
                      | Bool
    otherwise = a
    def
        go IntMap a
    Nil = a
    def

    -- | /O(log n)/. Find largest key smaller than the given one and return the
    -- corresponding (key, value) pair.
    --
    -- > lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
    -- > lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')

    -- See Note: Local 'go' functions and capturing.
    lookupLT :: Key -> IntMap a -> Maybe (Key, a)
    lookupLT :: forall a. Int -> IntMap a -> Maybe (Int, a)
    lookupLT !Int
    k IntMap a
    t = case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 then IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    r IntMap a
    l else IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    r
        IntMap a
    _ -> IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    t
      where
        go :: IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = if Int
    k forall a. Ord a => a -> a -> Bool
    < Int
    p then forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def else forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    r
          | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def IntMap a
    l
          | Bool
    otherwise = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    l IntMap a
    r
        go IntMap a
    def (Tip Int
    ky a
    y)
          | Int
    k forall a. Ord a => a -> a -> Bool
    <= Int
    ky   = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def
          | Bool
    otherwise = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
        go IntMap a
    def IntMap a
    Nil = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def

    -- | /O(log n)/. Find smallest key greater than the given one and return the
    -- corresponding (key, value) pair.
    --
    -- > lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
    -- > lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing

    -- See Note: Local 'go' functions and capturing.
    lookupGT :: Key -> IntMap a -> Maybe (Key, a)
    lookupGT :: forall a. Int -> IntMap a -> Maybe (Int, a)
    lookupGT !Int
    k IntMap a
    t = case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 then IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    l else IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    l IntMap a
    r
        IntMap a
    _ -> IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    t
      where
        go :: IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = if Int
    k forall a. Ord a => a -> a -> Bool
    < Int
    p then forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    l else forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def
          | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    r IntMap a
    l
          | Bool
    otherwise = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def IntMap a
    r
        go IntMap a
    def (Tip Int
    ky a
    y)
          | Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    ky   = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def
          | Bool
    otherwise = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
        go IntMap a
    def IntMap a
    Nil = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def

    -- | /O(log n)/. Find largest key smaller or equal to the given one and return
    -- the corresponding (key, value) pair.
    --
    -- > lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
    -- > lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
    -- > lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')

    -- See Note: Local 'go' functions and capturing.
    lookupLE :: Key -> IntMap a -> Maybe (Key, a)
    lookupLE :: forall a. Int -> IntMap a -> Maybe (Int, a)
    lookupLE !Int
    k IntMap a
    t = case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 then IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    r IntMap a
    l else IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    r
        IntMap a
    _ -> IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    t
      where
        go :: IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = if Int
    k forall a. Ord a => a -> a -> Bool
    < Int
    p then forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def else forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    r
          | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def IntMap a
    l
          | Bool
    otherwise = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    l IntMap a
    r
        go IntMap a
    def (Tip Int
    ky a
    y)
          | Int
    k forall a. Ord a => a -> a -> Bool
    < Int
    ky    = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def
          | Bool
    otherwise = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
        go IntMap a
    def IntMap a
    Nil = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    def

    -- | /O(log n)/. Find smallest key greater or equal to the given one and return
    -- the corresponding (key, value) pair.
    --
    -- > lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
    -- > lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
    -- > lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing

    -- See Note: Local 'go' functions and capturing.
    lookupGE :: Key -> IntMap a -> Maybe (Key, a)
    lookupGE :: forall a. Int -> IntMap a -> Maybe (Int, a)
    lookupGE !Int
    k IntMap a
    t = case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 then IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    l else IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    l IntMap a
    r
        IntMap a
    _ -> IntMap a -> IntMap a -> Maybe (Int, a)
    go forall a. IntMap a
    Nil IntMap a
    t
      where
        go :: IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = if Int
    k forall a. Ord a => a -> a -> Bool
    < Int
    p then forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    l else forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def
          | Int -> Int -> Bool
    zero Int
    k Int
    m  = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    r IntMap a
    l
          | Bool
    otherwise = IntMap a -> IntMap a -> Maybe (Int, a)
    go IntMap a
    def IntMap a
    r
        go IntMap a
    def (Tip Int
    ky a
    y)
          | Int
    k forall a. Ord a => a -> a -> Bool
    > Int
    ky    = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def
          | Bool
    otherwise = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
        go IntMap a
    def IntMap a
    Nil = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    def

    -- Helper function for lookupGE and lookupGT. It assumes that if a Bin node is
    -- given, it has m > 0.
    unsafeFindMin :: IntMap a -> Maybe (Key, a)
    unsafeFindMin :: forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    Nil = forall a. Maybe a
    Nothing
    unsafeFindMin (Tip Int
    ky a
    y) = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
    unsafeFindMin (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    _) = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMin IntMap a
    l

    -- Helper function for lookupLE and lookupLT. It assumes that if a Bin node is
    -- given, it has m > 0.
    unsafeFindMax :: IntMap a -> Maybe (Key, a)
    unsafeFindMax :: forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    Nil = forall a. Maybe a
    Nothing
    unsafeFindMax (Tip Int
    ky a
    y) = forall a. a -> Maybe a
    Just (Int
    ky, a
    y)
    unsafeFindMax (Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    r) = forall a. IntMap a -> Maybe (Int, a)
    unsafeFindMax IntMap a
    r

    {--------------------------------------------------------------------
      Disjoint
    --------------------------------------------------------------------}
    -- | /O(n+m)/. Check whether the key sets of two maps are disjoint
    -- (i.e. their 'intersection' is empty).
    --
    -- > disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
    -- > disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
    -- > disjoint (fromList [])        (fromList [])                 == True
    --
    -- > disjoint a b == null (intersection a b)
    --
    -- @since 0.6.2.1
    disjoint :: IntMap a -> IntMap b -> Bool
    disjoint :: forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    Nil IntMap b
    _ = Bool
    True
    disjoint IntMap a
    _ IntMap b
    Nil = Bool
    True
    disjoint (Tip Int
    kx a
    _) IntMap b
    ys = forall a. Int -> IntMap a -> Bool
    notMember Int
    kx IntMap b
    ys
    disjoint IntMap a
    xs (Tip Int
    ky b
    _) = forall a. Int -> IntMap a -> Bool
    notMember Int
    ky IntMap a
    xs
    disjoint t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) t2 :: IntMap b
    t2@(Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
      | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2 = Bool
    disjoint1
      | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1 = Bool
    disjoint2
      | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2      = forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    l1 IntMap b
    l2 Bool -> Bool -> Bool
    && forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    r1 IntMap b
    r2
      | Bool
    otherwise     = Bool
    True
      where
        disjoint1 :: Bool
    disjoint1 | Int -> Int -> Int -> Bool
    nomatch Int
    p2 Int
    p1 Int
    m1 = Bool
    True
                  | Int -> Int -> Bool
    zero Int
    p2 Int
    m1       = forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    l1 IntMap b
    t2
                  | Bool
    otherwise        = forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    r1 IntMap b
    t2
        disjoint2 :: Bool
    disjoint2 | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2 = Bool
    True
                  | Int -> Int -> Bool
    zero Int
    p1 Int
    m2       = forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    t1 IntMap b
    l2
                  | Bool
    otherwise        = forall a b. IntMap a -> IntMap b -> Bool
    disjoint IntMap a
    t1 IntMap b
    r2

    {--------------------------------------------------------------------
      Compose
    --------------------------------------------------------------------}
    -- | Relate the keys of one map to the values of
    -- the other, by using the values of the former as keys for lookups
    -- in the latter.
    --
    -- Complexity: \( O(n * \min(m,W)) \), where \(m\) is the size of the first argument
    --
    -- > compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
    --
    -- @
    -- ('compose' bc ab '!?') = (bc '!?') <=< (ab '!?')
    -- @
    --
    -- __Note:__ Prior to v0.6.4, "Data.IntMap.Strict" exposed a version of
    -- 'compose' that forced the values of the output 'IntMap'. This version does
    -- not force these values.
    --
    -- @since 0.6.3.1
    compose :: IntMap c -> IntMap Int -> IntMap c
    compose :: forall c. IntMap c -> IntMap Int -> IntMap c
    compose IntMap c
    bc !IntMap Int
    ab
      | forall a. IntMap a -> Bool
    null IntMap c
    bc = forall a. IntMap a
    empty
      | Bool
    otherwise = forall a b. (a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybe (IntMap c
    bc forall a. IntMap a -> Int -> Maybe a
    !?) IntMap Int
    ab

    {--------------------------------------------------------------------
      Construction
    --------------------------------------------------------------------}
    -- | /O(1)/. The empty map.
    --
    -- > empty      == fromList []
    -- > size empty == 0

    empty :: IntMap a
    empty :: forall a. IntMap a
    empty
      = forall a. IntMap a
    Nil
    {-# INLINE empty #-}

    -- | /O(1)/. A map of one element.
    --
    -- > singleton 1 'a'        == fromList [(1, 'a')]
    -- > size (singleton 1 'a') == 1

    singleton :: Key -> a -> IntMap a
    singleton :: forall a. Int -> a -> IntMap a
    singleton Int
    k a
    x
      = forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x
    {-# INLINE singleton #-}

    {--------------------------------------------------------------------
      Insert
    --------------------------------------------------------------------}
    -- | /O(min(n,W))/. Insert a new key\/value pair in the map.
    -- If the key is already present in the map, the associated value is
    -- replaced with the supplied value, i.e. 'insert' is equivalent to
    -- @'insertWith' 'const'@.
    --
    -- > insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
    -- > insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
    -- > insert 5 'x' empty                         == singleton 5 'x'

    insert :: Key -> a -> IntMap a -> IntMap a
    insert :: forall a. Int -> a -> IntMap a -> IntMap a
    insert !Int
    k a
    x t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    p IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (forall a. Int -> a -> IntMap a -> IntMap a
    insert Int
    k a
    x IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l (forall a. Int -> a -> IntMap a -> IntMap a
    insert Int
    k a
    x IntMap a
    r)
    insert Int
    k a
    x t :: IntMap a
    t@(Tip Int
    ky a
    _)
      | Int
    kforall a. Eq a => a -> a -> Bool
    ==Int
    ky         = forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x
      | Bool
    otherwise     = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    ky IntMap a
    t
    insert Int
    k a
    x IntMap a
    Nil = forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x

    -- right-biased insertion, used by 'union'
    -- | /O(min(n,W))/. Insert with a combining function.
    -- @'insertWith' f key value mp@
    -- will insert the pair (key, value) into @mp@ if key does
    -- not exist in the map. If the key does exist, the function will
    -- insert @f new_value old_value@.
    --
    -- > insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
    -- > insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
    -- > insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"

    insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
    insertWith :: forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWith a -> a -> a
    f Int
    k a
    x IntMap a
    t
      = forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWithKey (\Int
    _ a
    x' a
    y' -> a -> a -> a
    f a
    x' a
    y') Int
    k a
    x IntMap a
    t

    -- | /O(min(n,W))/. Insert with a combining function.
    -- @'insertWithKey' f key value mp@
    -- will insert the pair (key, value) into @mp@ if key does
    -- not exist in the map. If the key does exist, the function will
    -- insert @f key new_value old_value@.
    --
    -- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
    -- > insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
    -- > insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
    -- > insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"

    insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
    insertWithKey :: forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWithKey Int -> a -> a -> a
    f !Int
    k a
    x t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    p IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWithKey Int -> a -> a -> a
    f Int
    k a
    x IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l (forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWithKey Int -> a -> a -> a
    f Int
    k a
    x IntMap a
    r)
    insertWithKey Int -> a -> a -> a
    f Int
    k a
    x t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    ky       = forall a. Int -> a -> IntMap a
    Tip Int
    k (Int -> a -> a -> a
    f Int
    k a
    x a
    y)
      | Bool
    otherwise     = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    ky IntMap a
    t
    insertWithKey Int -> a -> a -> a
    _ Int
    k a
    x IntMap a
    Nil = forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x

    -- | /O(min(n,W))/. The expression (@'insertLookupWithKey' f k x map@)
    -- is a pair where the first element is equal to (@'lookup' k map@)
    -- and the second element equal to (@'insertWithKey' f k x map@).
    --
    -- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
    -- > insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
    -- > insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
    -- > insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
    --
    -- This is how to define @insertLookup@ using @insertLookupWithKey@:
    --
    -- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t
    -- > insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
    -- > insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])

    insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)
    insertLookupWithKey :: forall a.
    (Int -> a -> a -> a) -> Int -> a -> IntMap a -> (Maybe a, IntMap a)
    insertLookupWithKey Int -> a -> a -> a
    f !Int
    k a
    x t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = (forall a. Maybe a
    Nothing,forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    p IntMap a
    t)
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = let (Maybe a
    found,IntMap a
    l') = forall a.
    (Int -> a -> a -> a) -> Int -> a -> IntMap a -> (Maybe a, IntMap a)
    insertLookupWithKey Int -> a -> a -> a
    f Int
    k a
    x IntMap a
    l
                        in (Maybe a
    found,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l' IntMap a
    r)
      | Bool
    otherwise     = let (Maybe a
    found,IntMap a
    r') = forall a.
    (Int -> a -> a -> a) -> Int -> a -> IntMap a -> (Maybe a, IntMap a)
    insertLookupWithKey Int -> a -> a -> a
    f Int
    k a
    x IntMap a
    r
                        in (Maybe a
    found,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l IntMap a
    r')
    insertLookupWithKey Int -> a -> a -> a
    f Int
    k a
    x t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    ky       = (forall a. a -> Maybe a
    Just a
    y,forall a. Int -> a -> IntMap a
    Tip Int
    k (Int -> a -> a -> a
    f Int
    k a
    x a
    y))
      | Bool
    otherwise     = (forall a. Maybe a
    Nothing,forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    ky IntMap a
    t)
    insertLookupWithKey Int -> a -> a -> a
    _ Int
    k a
    x IntMap a
    Nil = (forall a. Maybe a
    Nothing,forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x)

    {--------------------------------------------------------------------
      Deletion
    --------------------------------------------------------------------}
    -- | /O(min(n,W))/. Delete a key and its value from the map. When the key is not
    -- a member of the map, the original map is returned.
    --
    -- > delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
    -- > delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
    -- > delete 5 empty                         == empty

    delete :: Key -> IntMap a -> IntMap a
    delete :: forall a. Int -> IntMap a -> IntMap a
    delete !Int
    k t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m (forall a. Int -> IntMap a -> IntMap a
    delete Int
    k IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l (forall a. Int -> IntMap a -> IntMap a
    delete Int
    k IntMap a
    r)
    delete Int
    k t :: IntMap a
    t@(Tip Int
    ky a
    _)
      | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    ky       = forall a. IntMap a
    Nil
      | Bool
    otherwise     = IntMap a
    t
    delete Int
    _k IntMap a
    Nil = forall a. IntMap a
    Nil

    -- | /O(min(n,W))/. Adjust a value at a specific key. When the key is not
    -- a member of the map, the original map is returned.
    --
    -- > adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
    -- > adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
    -- > adjust ("new " ++) 7 empty                         == empty

    adjust ::  (a -> a) -> Key -> IntMap a -> IntMap a
    adjust :: forall a. (a -> a) -> Int -> IntMap a -> IntMap a
    adjust a -> a
    f Int
    k IntMap a
    m
      = forall a. (Int -> a -> a) -> Int -> IntMap a -> IntMap a
    adjustWithKey (\Int
    _ a
    x -> a -> a
    f a
    x) Int
    k IntMap a
    m

    -- | /O(min(n,W))/. Adjust a value at a specific key. When the key is not
    -- a member of the map, the original map is returned.
    --
    -- > let f key x = (show key) ++ ":new " ++ x
    -- > adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
    -- > adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
    -- > adjustWithKey f 7 empty                         == empty

    adjustWithKey ::  (Key -> a -> a) -> Key -> IntMap a -> IntMap a
    adjustWithKey :: forall a. (Int -> a -> a) -> Int -> IntMap a -> IntMap a
    adjustWithKey Int -> a -> a
    f !Int
    k t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (forall a. (Int -> a -> a) -> Int -> IntMap a -> IntMap a
    adjustWithKey Int -> a -> a
    f Int
    k IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l (forall a. (Int -> a -> a) -> Int -> IntMap a -> IntMap a
    adjustWithKey Int -> a -> a
    f Int
    k IntMap a
    r)
    adjustWithKey Int -> a -> a
    f Int
    k t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    ky       = forall a. Int -> a -> IntMap a
    Tip Int
    ky (Int -> a -> a
    f Int
    k a
    y)
      | Bool
    otherwise     = IntMap a
    t
    adjustWithKey Int -> a -> a
    _ Int
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    -- | /O(min(n,W))/. The expression (@'update' f k map@) updates the value @x@
    -- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is
    -- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.
    --
    -- > let f x = if x == "a" then Just "new a" else Nothing
    -- > update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
    -- > update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
    -- > update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"

    update ::  (a -> Maybe a) -> Key -> IntMap a -> IntMap a
    update :: forall a. (a -> Maybe a) -> Int -> IntMap a -> IntMap a
    update a -> Maybe a
    f
      = forall a. (Int -> a -> Maybe a) -> Int -> IntMap a -> IntMap a
    updateWithKey (\Int
    _ a
    x -> a -> Maybe a
    f a
    x)

    -- | /O(min(n,W))/. The expression (@'update' f k map@) updates the value @x@
    -- at @k@ (if it is in the map). If (@f k x@) is 'Nothing', the element is
    -- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.
    --
    -- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
    -- > updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
    -- > updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
    -- > updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"

    updateWithKey ::  (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a
    updateWithKey :: forall a. (Int -> a -> Maybe a) -> Int -> IntMap a -> IntMap a
    updateWithKey Int -> a -> Maybe a
    f !Int
    k t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m (forall a. (Int -> a -> Maybe a) -> Int -> IntMap a -> IntMap a
    updateWithKey Int -> a -> Maybe a
    f Int
    k IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l (forall a. (Int -> a -> Maybe a) -> Int -> IntMap a -> IntMap a
    updateWithKey Int -> a -> Maybe a
    f Int
    k IntMap a
    r)
    updateWithKey Int -> a -> Maybe a
    f Int
    k t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    k forall a. Eq a => a -> a -> Bool
    == Int
    ky       = case (Int -> a -> Maybe a
    f Int
    k a
    y) of
                          Just a
    y' -> forall a. Int -> a -> IntMap a
    Tip Int
    ky a
    y'
                          Maybe a
    Nothing -> forall a. IntMap a
    Nil
      | Bool
    otherwise     = IntMap a
    t
    updateWithKey Int -> a -> Maybe a
    _ Int
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    -- | /O(min(n,W))/. Lookup and update.
    -- The function returns original value, if it is updated.
    -- This is different behavior than 'Data.Map.updateLookupWithKey'.
    -- Returns the original key value if the map entry is deleted.
    --
    -- > let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
    -- > updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
    -- > updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
    -- > updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")

    updateLookupWithKey ::  (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a,IntMap a)
    updateLookupWithKey :: forall a.
    (Int -> a -> Maybe a) -> Int -> IntMap a -> (Maybe a, IntMap a)
    updateLookupWithKey Int -> a -> Maybe a
    f !Int
    k t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = (forall a. Maybe a
    Nothing,IntMap a
    t)
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = let !(Maybe a
    found,IntMap a
    l') = forall a.
    (Int -> a -> Maybe a) -> Int -> IntMap a -> (Maybe a, IntMap a)
    updateLookupWithKey Int -> a -> Maybe a
    f Int
    k IntMap a
    l
                        in (Maybe a
    found,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m IntMap a
    l' IntMap a
    r)
      | Bool
    otherwise     = let !(Maybe a
    found,IntMap a
    r') = forall a.
    (Int -> a -> Maybe a) -> Int -> IntMap a -> (Maybe a, IntMap a)
    updateLookupWithKey Int -> a -> Maybe a
    f Int
    k IntMap a
    r
                        in (Maybe a
    found,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l IntMap a
    r')
    updateLookupWithKey Int -> a -> Maybe a
    f Int
    k t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    kforall a. Eq a => a -> a -> Bool
    ==Int
    ky         = case (Int -> a -> Maybe a
    f Int
    k a
    y) of
                          Just a
    y' -> (forall a. a -> Maybe a
    Just a
    y,forall a. Int -> a -> IntMap a
    Tip Int
    ky a
    y')
                          Maybe a
    Nothing -> (forall a. a -> Maybe a
    Just a
    y,forall a. IntMap a
    Nil)
      | Bool
    otherwise     = (forall a. Maybe a
    Nothing,IntMap a
    t)
    updateLookupWithKey Int -> a -> Maybe a
    _ Int
    _ IntMap a
    Nil = (forall a. Maybe a
    Nothing,forall a. IntMap a
    Nil)

    -- | /O(min(n,W))/. The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence thereof.
    -- 'alter' can be used to insert, delete, or update a value in an 'IntMap'.
    -- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.
    alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a
    alter :: forall a. (Maybe a -> Maybe a) -> Int -> IntMap a -> IntMap a
    alter Maybe a -> Maybe a
    f !Int
    k t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int -> Int -> Int -> Bool
    nomatch Int
    k Int
    p Int
    m = case Maybe a -> Maybe a
    f forall a. Maybe a
    Nothing of
                          Maybe a
    Nothing -> IntMap a
    t
                          Just a
    x -> forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    p IntMap a
    t
      | Int -> Int -> Bool
    zero Int
    k Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m (forall a. (Maybe a -> Maybe a) -> Int -> IntMap a -> IntMap a
    alter Maybe a -> Maybe a
    f Int
    k IntMap a
    l) IntMap a
    r
      | Bool
    otherwise     = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l (forall a. (Maybe a -> Maybe a) -> Int -> IntMap a -> IntMap a
    alter Maybe a -> Maybe a
    f Int
    k IntMap a
    r)
    alter Maybe a -> Maybe a
    f Int
    k t :: IntMap a
    t@(Tip Int
    ky a
    y)
      | Int
    kforall a. Eq a => a -> a -> Bool
    ==Int
    ky         = case Maybe a -> Maybe a
    f (forall a. a -> Maybe a
    Just a
    y) of
                          Just a
    x -> forall a. Int -> a -> IntMap a
    Tip Int
    ky a
    x
                          Maybe a
    Nothing -> forall a. IntMap a
    Nil
      | Bool
    otherwise     = case Maybe a -> Maybe a
    f forall a. Maybe a
    Nothing of
                          Just a
    x -> forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x) Int
    ky IntMap a
    t
                          Maybe a
    Nothing -> forall a. Int -> a -> IntMap a
    Tip Int
    ky a
    y
    alter Maybe a -> Maybe a
    f Int
    k IntMap a
    Nil     = case Maybe a -> Maybe a
    f forall a. Maybe a
    Nothing of
                          Just a
    x -> forall a. Int -> a -> IntMap a
    Tip Int
    k a
    x
                          Maybe a
    Nothing -> forall a. IntMap a
    Nil

    -- | /O(log n)/. The expression (@'alterF' f k map@) alters the value @x@ at
    -- @k@, or absence thereof.  'alterF' can be used to inspect, insert, delete,
    -- or update a value in an 'IntMap'.  In short : @'lookup' k <$> 'alterF' f k m = f
    -- ('lookup' k m)@.
    --
    -- Example:
    --
    -- @
    -- interactiveAlter :: Int -> IntMap String -> IO (IntMap String)
    -- interactiveAlter k m = alterF f k m where
    --   f Nothing = do
    --      putStrLn $ show k ++
    --          " was not found in the map. Would you like to add it?"
    --      getUserResponse1 :: IO (Maybe String)
    --   f (Just old) = do
    --      putStrLn $ "The key is currently bound to " ++ show old ++
    --          ". Would you like to change or delete it?"
    --      getUserResponse2 :: IO (Maybe String)
    -- @
    --
    -- 'alterF' is the most general operation for working with an individual
    -- key that may or may not be in a given map.
    --
    -- Note: 'alterF' is a flipped version of the @at@ combinator from
    -- @Control.Lens.At@.
    --
    -- @since 0.5.8

    alterF :: Functor f
           => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)
    -- This implementation was stolen from 'Control.Lens.At'.
    alterF :: forall (f :: * -> *) a.
    Functor f =>
    (Maybe a -> f (Maybe a)) -> Int -> IntMap a -> f (IntMap a)
    alterF Maybe a -> f (Maybe a)
    f Int
    k IntMap a
    m = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe a -> f (Maybe a)
    f Maybe a
    mv) forall a b. (a -> b) -> a -> b
    $ \Maybe a
    fres ->
      case Maybe a
    fres of
        Maybe a
    Nothing -> forall b a. b -> (a -> b) -> Maybe a -> b
    maybe IntMap a
    m (forall a b. a -> b -> a
    const (forall a. Int -> IntMap a -> IntMap a
    delete Int
    k IntMap a
    m)) Maybe a
    mv
        Just a
    v' -> forall a. Int -> a -> IntMap a -> IntMap a
    insert Int
    k a
    v' IntMap a
    m
      where mv :: Maybe a
    mv = forall a. Int -> IntMap a -> Maybe a
    lookup Int
    k IntMap a
    m

    {--------------------------------------------------------------------
      Union
    --------------------------------------------------------------------}
    -- | The union of a list of maps.
    --
    -- > unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
    -- >     == fromList [(3, "b"), (5, "a"), (7, "C")]
    -- > unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
    -- >     == fromList [(3, "B3"), (5, "A3"), (7, "C")]

    unions :: Foldable f => f (IntMap a) -> IntMap a
    unions :: forall (f :: * -> *) a. Foldable f => f (IntMap a) -> IntMap a
    unions f (IntMap a)
    xs
      = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' forall a. IntMap a -> IntMap a -> IntMap a
    union forall a. IntMap a
    empty f (IntMap a)
    xs

    -- | The union of a list of maps, with a combining operation.
    --
    -- > unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
    -- >     == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]

    unionsWith :: Foldable f => (a->a->a) -> f (IntMap a) -> IntMap a
    unionsWith :: forall (f :: * -> *) a.
    Foldable f =>
    (a -> a -> a) -> f (IntMap a) -> IntMap a
    unionsWith a -> a -> a
    f f (IntMap a)
    ts
      = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' (forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWith a -> a -> a
    f) forall a. IntMap a
    empty f (IntMap a)
    ts

    -- | /O(n+m)/. The (left-biased) union of two maps.
    -- It prefers the first map when duplicate keys are encountered,
    -- i.e. (@'union' == 'unionWith' 'const'@).
    --
    -- > union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]

    union :: IntMap a -> IntMap a -> IntMap a
    union :: forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    m1 IntMap a
    m2
      = forall c a b.
    (Int -> Int -> 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
    mergeWithKey' forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin forall a b. a -> b -> a
    const forall a. a -> a
    id forall a. a -> a
    id IntMap a
    m1 IntMap a
    m2

    -- | /O(n+m)/. The union with a combining function.
    --
    -- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]

    unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWith :: forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWith a -> a -> a
    f IntMap a
    m1 IntMap a
    m2
      = forall a. (Int -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWithKey (\Int
    _ a
    x a
    y -> a -> a -> a
    f a
    x a
    y) IntMap a
    m1 IntMap a
    m2

    -- | /O(n+m)/. The union with a combining function.
    --
    -- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
    -- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]

    unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWithKey :: forall a. (Int -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
    unionWithKey Int -> a -> a -> a
    f IntMap a
    m1 IntMap a
    m2
      = forall c a b.
    (Int -> Int -> 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
    mergeWithKey' forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin (\(Tip Int
    k1 a
    x1) (Tip Int
    _k2 a
    x2) -> forall a. Int -> a -> IntMap a
    Tip Int
    k1 (Int -> a -> a -> a
    f Int
    k1 a
    x1 a
    x2)) forall a. a -> a
    id forall a. a -> a
    id IntMap a
    m1 IntMap a
    m2

    {--------------------------------------------------------------------
      Difference
    --------------------------------------------------------------------}
    -- | /O(n+m)/. Difference between two maps (based on keys).
    --
    -- > difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"

    difference :: IntMap a -> IntMap b -> IntMap a
    difference :: forall a b. IntMap a -> IntMap b -> IntMap a
    difference IntMap a
    m1 IntMap b
    m2
      = forall a b c.
    (Int -> a -> b -> Maybe c)
    -> (IntMap a -> IntMap c)
    -> (IntMap b -> IntMap c)
    -> IntMap a
    -> IntMap b
    -> IntMap c
    mergeWithKey (\Int
    _ a
    _ b
    _ -> forall a. Maybe a
    Nothing) forall a. a -> a
    id (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) IntMap a
    m1 IntMap b
    m2

    -- | /O(n+m)/. Difference with a combining function.
    --
    -- > let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
    -- > differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
    -- >     == singleton 3 "b:B"

    differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
    differenceWith :: forall a b. (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
    differenceWith a -> b -> Maybe a
    f IntMap a
    m1 IntMap b
    m2
      = forall a b.
    (Int -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
    differenceWithKey (\Int
    _ a
    x b
    y -> a -> b -> Maybe a
    f a
    x b
    y) IntMap a
    m1 IntMap b
    m2

    -- | /O(n+m)/. Difference with a combining function. When two equal keys are
    -- encountered, the combining function is applied to the key and both values.
    -- If it returns 'Nothing', the element is discarded (proper set difference).
    -- If it returns (@'Just' y@), the element is updated with a new value @y@.
    --
    -- > let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
    -- > differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
    -- >     == singleton 3 "3:b|B"

    differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
    differenceWithKey :: forall a b.
    (Int -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
    differenceWithKey Int -> a -> b -> Maybe a
    f IntMap a
    m1 IntMap b
    m2
      = forall a b c.
    (Int -> a -> b -> Maybe c)
    -> (IntMap a -> IntMap c)
    -> (IntMap b -> IntMap c)
    -> IntMap a
    -> IntMap b
    -> IntMap c
    mergeWithKey Int -> a -> b -> Maybe a
    f forall a. a -> a
    id (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) IntMap a
    m1 IntMap b
    m2

    -- TODO(wrengr): re-verify that asymptotic bound
    -- | /O(n+m)/. Remove all the keys in a given set from a map.
    --
    -- @
    -- m \`withoutKeys\` s = 'filterWithKey' (\k _ -> k ``IntSet.notMember`` s) m
    -- @
    --
    -- @since 0.5.8
    withoutKeys :: IntMap a -> IntSet.IntSet -> IntMap a
    withoutKeys :: forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) t2 :: IntSet
    t2@(IntSet.Bin Int
    p2 Int
    m2 IntSet
    l2 IntSet
    r2)
        | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = IntMap a
    difference1
        | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = IntMap a
    difference2
        | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2       = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p1 Int
    m1 (forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    l1 IntSet
    l2) (forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    r1 IntSet
    r2)
        | Bool
    otherwise      = IntMap a
    t1
        where
        difference1 :: IntMap a
    difference1
            | Int -> Int -> Int -> Bool
    nomatch Int
    p2 Int
    p1 Int
    m1  = IntMap a
    t1
            | Int -> Int -> Bool
    zero Int
    p2 Int
    m1        = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p1 Int
    m1 (forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    l1 IntSet
    t2) IntMap a
    r1
            | Bool
    otherwise         = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p1 Int
    m1 IntMap a
    l1 (forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    r1 IntSet
    t2)
        difference2 :: IntMap a
    difference2
            | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2  = IntMap a
    t1
            | Int -> Int -> Bool
    zero Int
    p1 Int
    m2        = forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    t1 IntSet
    l2
            | Bool
    otherwise         = forall a. IntMap a -> IntSet -> IntMap a
    withoutKeys IntMap a
    t1 IntSet
    r2
    withoutKeys t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    _ IntMap a
    _) (IntSet.Tip Int
    p2 Nat
    bm2) =
        let minbit :: Nat
    minbit = Int -> Nat
    bitmapOf Int
    p1
            lt_minbit :: Nat
    lt_minbit = Nat
    minbit forall a. Num a => a -> a -> a
    - Nat
    1
            maxbit :: Nat
    maxbit = Int -> Nat
    bitmapOf (Int
    p1 forall a. Bits a => a -> a -> a
    .|. (Int
    m1 forall a. Bits a => a -> a -> a
    .|. (Int
    m1 forall a. Num a => a -> a -> a
    - Int
    1)))
            gt_maxbit :: Nat
    gt_maxbit = (-Nat
    maxbit) forall a. Bits a => a -> a -> a
    `xor` Nat
    maxbit
        -- TODO(wrengr): should we manually inline/unroll 'updatePrefix'
        -- and 'withoutBM' here, in order to avoid redundant case analyses?
        in forall a. Int -> IntMap a -> (IntMap a -> IntMap a) -> IntMap a
    updatePrefix Int
    p2 IntMap a
    t1 forall a b. (a -> b) -> a -> b
    $ forall a. Nat -> IntMap a -> IntMap a
    withoutBM (Nat
    bm2 forall a. Bits a => a -> a -> a
    .|. Nat
    lt_minbit forall a. Bits a => a -> a -> a
    .|. Nat
    gt_maxbit)
    withoutKeys t1 :: IntMap a
    t1@(Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) IntSet
    IntSet.Nil = IntMap a
    t1
    withoutKeys t1 :: IntMap a
    t1@(Tip Int
    k1 a
    _) IntSet
    t2
        | Int
    k1 Int -> IntSet -> Bool
    `IntSet.member` IntSet
    t2 = forall a. IntMap a
    Nil
        | Bool
    otherwise = IntMap a
    t1
    withoutKeys IntMap a
    Nil IntSet
    _ = forall a. IntMap a
    Nil

    updatePrefix
        :: IntSetPrefix -> IntMap a -> (IntMap a -> IntMap a) -> IntMap a
    updatePrefix :: forall a. Int -> IntMap a -> (IntMap a -> IntMap a) -> IntMap a
    updatePrefix !Int
    kp t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) IntMap a -> IntMap a
    f
        | Int
    m forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.suffixBitMask forall a. Eq a => a -> a -> Bool
    /= Int
    0 =
            if Int
    p forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask forall a. Eq a => a -> a -> Bool
    == Int
    kp then IntMap a -> IntMap a
    f IntMap a
    t else IntMap a
    t
        | Int -> Int -> Int -> Bool
    nomatch Int
    kp Int
    p Int
    m = IntMap a
    t
        | Int -> Int -> Bool
    zero Int
    kp Int
    m      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m (forall a. Int -> IntMap a -> (IntMap a -> IntMap a) -> IntMap a
    updatePrefix Int
    kp IntMap a
    l IntMap a -> IntMap a
    f) IntMap a
    r
        | Bool
    otherwise      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l (forall a. Int -> IntMap a -> (IntMap a -> IntMap a) -> IntMap a
    updatePrefix Int
    kp IntMap a
    r IntMap a -> IntMap a
    f)
    updatePrefix Int
    kp t :: IntMap a
    t@(Tip Int
    kx a
    _) IntMap a -> IntMap a
    f
        | Int
    kx forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask forall a. Eq a => a -> a -> Bool
    == Int
    kp = IntMap a -> IntMap a
    f IntMap a
    t
        | Bool
    otherwise = IntMap a
    t
    updatePrefix Int
    _ IntMap a
    Nil IntMap a -> IntMap a
    _ = forall a. IntMap a
    Nil

    withoutBM :: IntSetBitMap -> IntMap a -> IntMap a
    withoutBM :: forall a. Nat -> IntMap a -> IntMap a
    withoutBM Nat
    0 IntMap a
    t = IntMap a
    t
    withoutBM Nat
    bm (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) =
        let leftBits :: Nat
    leftBits = Int -> Nat
    bitmapOf (Int
    p forall a. Bits a => a -> a -> a
    .|. Int
    m) forall a. Num a => a -> a -> a
    - Nat
    1
            bmL :: Nat
    bmL = Nat
    bm forall a. Bits a => a -> a -> a
    .&. Nat
    leftBits
            bmR :: Nat
    bmR = Nat
    bm forall a. Bits a => a -> a -> a
    `xor` Nat
    bmL -- = (bm .&. complement leftBits)
        in  forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m (forall a. Nat -> IntMap a -> IntMap a
    withoutBM Nat
    bmL IntMap a
    l) (forall a. Nat -> IntMap a -> IntMap a
    withoutBM Nat
    bmR IntMap a
    r)
    withoutBM Nat
    bm t :: IntMap a
    t@(Tip Int
    k a
    _)
        -- TODO(wrengr): need we manually inline 'IntSet.Member' here?
        | Int
    k Int -> IntSet -> Bool
    `IntSet.member` Int -> Nat -> IntSet
    IntSet.Tip (Int
    k forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask) Nat
    bm = forall a. IntMap a
    Nil
        | Bool
    otherwise = IntMap a
    t
    withoutBM Nat
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    {--------------------------------------------------------------------
      Intersection
    --------------------------------------------------------------------}
    -- | /O(n+m)/. The (left-biased) intersection of two maps (based on keys).
    --
    -- > intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"

    intersection :: IntMap a -> IntMap b -> IntMap a
    intersection :: forall a b. IntMap a -> IntMap b -> IntMap a
    intersection IntMap a
    m1 IntMap b
    m2
      = forall c a b.
    (Int -> Int -> 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
    mergeWithKey' forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin forall a b. a -> b -> a
    const (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) IntMap a
    m1 IntMap b
    m2

    -- TODO(wrengr): re-verify that asymptotic bound
    -- | /O(n+m)/. The restriction of a map to the keys in a set.
    --
    -- @
    -- m \`restrictKeys\` s = 'filterWithKey' (\k _ -> k ``IntSet.member`` s) m
    -- @
    --
    -- @since 0.5.8
    restrictKeys :: IntMap a -> IntSet.IntSet -> IntMap a
    restrictKeys :: forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) t2 :: IntSet
    t2@(IntSet.Bin Int
    p2 Int
    m2 IntSet
    l2 IntSet
    r2)
        | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = IntMap a
    intersection1
        | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = IntMap a
    intersection2
        | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2       = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p1 Int
    m1 (forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    l1 IntSet
    l2) (forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    r1 IntSet
    r2)
        | Bool
    otherwise      = forall a. IntMap a
    Nil
        where
        intersection1 :: IntMap a
    intersection1
            | Int -> Int -> Int -> Bool
    nomatch Int
    p2 Int
    p1 Int
    m1  = forall a. IntMap a
    Nil
            | Int -> Int -> Bool
    zero Int
    p2 Int
    m1        = forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    l1 IntSet
    t2
            | Bool
    otherwise         = forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    r1 IntSet
    t2
        intersection2 :: IntMap a
    intersection2
            | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2  = forall a. IntMap a
    Nil
            | Int -> Int -> Bool
    zero Int
    p1 Int
    m2        = forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    t1 IntSet
    l2
            | Bool
    otherwise         = forall a. IntMap a -> IntSet -> IntMap a
    restrictKeys IntMap a
    t1 IntSet
    r2
    restrictKeys t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    _ IntMap a
    _) (IntSet.Tip Int
    p2 Nat
    bm2) =
        let minbit :: Nat
    minbit = Int -> Nat
    bitmapOf Int
    p1
            ge_minbit :: Nat
    ge_minbit = forall a. Bits a => a -> a
    complement (Nat
    minbit forall a. Num a => a -> a -> a
    - Nat
    1)
            maxbit :: Nat
    maxbit = Int -> Nat
    bitmapOf (Int
    p1 forall a. Bits a => a -> a -> a
    .|. (Int
    m1 forall a. Bits a => a -> a -> a
    .|. (Int
    m1 forall a. Num a => a -> a -> a
    - Int
    1)))
            le_maxbit :: Nat
    le_maxbit = Nat
    maxbit forall a. Bits a => a -> a -> a
    .|. (Nat
    maxbit forall a. Num a => a -> a -> a
    - Nat
    1)
        -- TODO(wrengr): should we manually inline/unroll 'lookupPrefix'
        -- and 'restrictBM' here, in order to avoid redundant case analyses?
        in forall a. Nat -> IntMap a -> IntMap a
    restrictBM (Nat
    bm2 forall a. Bits a => a -> a -> a
    .&. Nat
    ge_minbit forall a. Bits a => a -> a -> a
    .&. Nat
    le_maxbit) (forall a. Int -> IntMap a -> IntMap a
    lookupPrefix Int
    p2 IntMap a
    t1)
    restrictKeys (Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) IntSet
    IntSet.Nil = forall a. IntMap a
    Nil
    restrictKeys t1 :: IntMap a
    t1@(Tip Int
    k1 a
    _) IntSet
    t2
        | Int
    k1 Int -> IntSet -> Bool
    `IntSet.member` IntSet
    t2 = IntMap a
    t1
        | Bool
    otherwise = forall a. IntMap a
    Nil
    restrictKeys IntMap a
    Nil IntSet
    _ = forall a. IntMap a
    Nil

    -- | /O(min(n,W))/. Restrict to the sub-map with all keys matching
    -- a key prefix.
    lookupPrefix :: IntSetPrefix -> IntMap a -> IntMap a
    lookupPrefix :: forall a. Int -> IntMap a -> IntMap a
    lookupPrefix !Int
    kp t :: IntMap a
    t@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
        | Int
    m forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.suffixBitMask forall a. Eq a => a -> a -> Bool
    /= Int
    0 =
            if Int
    p forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask forall a. Eq a => a -> a -> Bool
    == Int
    kp then IntMap a
    t else forall a. IntMap a
    Nil
        | Int -> Int -> Int -> Bool
    nomatch Int
    kp Int
    p Int
    m = forall a. IntMap a
    Nil
        | Int -> Int -> Bool
    zero Int
    kp Int
    m      = forall a. Int -> IntMap a -> IntMap a
    lookupPrefix Int
    kp IntMap a
    l
        | Bool
    otherwise      = forall a. Int -> IntMap a -> IntMap a
    lookupPrefix Int
    kp IntMap a
    r
    lookupPrefix Int
    kp t :: IntMap a
    t@(Tip Int
    kx a
    _)
        | (Int
    kx forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask) forall a. Eq a => a -> a -> Bool
    == Int
    kp = IntMap a
    t
        | Bool
    otherwise = forall a. IntMap a
    Nil
    lookupPrefix Int
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    restrictBM :: IntSetBitMap -> IntMap a -> IntMap a
    restrictBM :: forall a. Nat -> IntMap a -> IntMap a
    restrictBM Nat
    0 IntMap a
    _ = forall a. IntMap a
    Nil
    restrictBM Nat
    bm (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) =
        let leftBits :: Nat
    leftBits = Int -> Nat
    bitmapOf (Int
    p forall a. Bits a => a -> a -> a
    .|. Int
    m) forall a. Num a => a -> a -> a
    - Nat
    1
            bmL :: Nat
    bmL = Nat
    bm forall a. Bits a => a -> a -> a
    .&. Nat
    leftBits
            bmR :: Nat
    bmR = Nat
    bm forall a. Bits a => a -> a -> a
    `xor` Nat
    bmL -- = (bm .&. complement leftBits)
        in  forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m (forall a. Nat -> IntMap a -> IntMap a
    restrictBM Nat
    bmL IntMap a
    l) (forall a. Nat -> IntMap a -> IntMap a
    restrictBM Nat
    bmR IntMap a
    r)
    restrictBM Nat
    bm t :: IntMap a
    t@(Tip Int
    k a
    _)
        -- TODO(wrengr): need we manually inline 'IntSet.Member' here?
        | Int
    k Int -> IntSet -> Bool
    `IntSet.member` Int -> Nat -> IntSet
    IntSet.Tip (Int
    k forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask) Nat
    bm = IntMap a
    t
        | Bool
    otherwise = forall a. IntMap a
    Nil
    restrictBM Nat
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    -- | /O(n+m)/. The intersection with a combining function.
    --
    -- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"

    intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
    intersectionWith :: forall a b c. (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
    intersectionWith a -> b -> c
    f IntMap a
    m1 IntMap b
    m2
      = forall a b c.
    (Int -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
    intersectionWithKey (\Int
    _ a
    x b
    y -> a -> b -> c
    f a
    x b
    y) IntMap a
    m1 IntMap b
    m2

    -- | /O(n+m)/. The intersection with a combining function.
    --
    -- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
    -- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"

    intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
    intersectionWithKey :: forall a b c.
    (Int -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
    intersectionWithKey Int -> a -> b -> c
    f IntMap a
    m1 IntMap b
    m2
      = forall c a b.
    (Int -> Int -> 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
    mergeWithKey' forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin (\(Tip Int
    k1 a
    x1) (Tip Int
    _k2 b
    x2) -> forall a. Int -> a -> IntMap a
    Tip Int
    k1 (Int -> a -> b -> c
    f Int
    k1 a
    x1 b
    x2)) (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) (forall a b. a -> b -> a
    const forall a. IntMap a
    Nil) IntMap a
    m1 IntMap b
    m2

    {--------------------------------------------------------------------
      MergeWithKey
    --------------------------------------------------------------------}

    -- | /O(n+m)/. A high-performance universal combining function. Using
    -- 'mergeWithKey', all combining functions can be defined without any loss of
    -- efficiency (with exception of 'union', 'difference' and 'intersection',
    -- where sharing of some nodes is lost with 'mergeWithKey').
    --
    -- Please make sure you know what is going on when using 'mergeWithKey',
    -- otherwise you can be surprised by unexpected code growth or even
    -- corruption of the data structure.
    --
    -- When 'mergeWithKey' is given three arguments, it is inlined to the call
    -- site. You should therefore use 'mergeWithKey' only to define your custom
    -- combining functions. For example, you could define 'unionWithKey',
    -- 'differenceWithKey' and 'intersectionWithKey' as
    --
    -- > myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) id id m1 m2
    -- > myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
    -- > myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -> Just (f k x1 x2)) (const empty) (const empty) m1 m2
    --
    -- When calling @'mergeWithKey' combine only1 only2@, a function combining two
    -- 'IntMap's is created, such that
    --
    -- * if a key is present in both maps, it is passed with both corresponding
    --   values to the @combine@ function. Depending on the result, the key is either
    --   present in the result with specified value, or is left out;
    --
    -- * a nonempty subtree present only in the first map is passed to @only1@ and
    --   the output is added to the result;
    --
    -- * a nonempty subtree present only in the second map is passed to @only2@ and
    --   the output is added to the result.
    --
    -- The @only1@ and @only2@ methods /must return a map with a subset (possibly empty) of the keys of the given map/.
    -- The values can be modified arbitrarily. Most common variants of @only1@ and
    -- @only2@ are 'id' and @'const' 'empty'@, but for example @'map' f@ or
    -- @'filterWithKey' f@ could be used for any @f@.

    mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c)
                 -> IntMap a -> IntMap b -> IntMap c
    mergeWithKey :: forall a b c.
    (Int -> a -> b -> Maybe c)
    -> (IntMap a -> IntMap c)
    -> (IntMap b -> IntMap c)
    -> IntMap a
    -> IntMap b
    -> IntMap c
    mergeWithKey Int -> a -> b -> Maybe c
    f IntMap a -> IntMap c
    g1 IntMap b -> IntMap c
    g2 = forall c a b.
    (Int -> Int -> 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
    mergeWithKey' forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin IntMap a -> IntMap b -> IntMap c
    combine IntMap a -> IntMap c
    g1 IntMap b -> IntMap c
    g2
      where -- We use the lambda form to avoid non-exhaustive pattern matches warning.
            combine :: IntMap a -> IntMap b -> IntMap c
    combine = \(Tip Int
    k1 a
    x1) (Tip Int
    _k2 b
    x2) ->
              case Int -> a -> b -> Maybe c
    f Int
    k1 a
    x1 b
    x2 of
                Maybe c
    Nothing -> forall a. IntMap a
    Nil
                Just c
    x -> forall a. Int -> a -> IntMap a
    Tip Int
    k1 c
    x
            {-# INLINE combine #-}
    {-# INLINE mergeWithKey #-}

    -- Slightly more general version of mergeWithKey. It differs in the following:
    --
    -- * the combining function operates on maps instead of keys and values. The
    --   reason is to enable sharing in union, difference and intersection.
    --
    -- * mergeWithKey' is given an equivalent of bin. The reason is that in union*,
    --   Bin constructor can be used, because we know both subtrees are nonempty.

    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
    mergeWithKey' :: forall c a b.
    (Int -> Int -> 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
    mergeWithKey' Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' IntMap a -> IntMap b -> IntMap c
    f IntMap a -> IntMap c
    g1 IntMap b -> IntMap c
    g2 = IntMap a -> IntMap b -> IntMap c
    go
      where
        go :: IntMap a -> IntMap b -> IntMap c
    go t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) t2 :: IntMap b
    t2@(Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
          | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = IntMap c
    merge1
          | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = IntMap c
    merge2
          | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2       = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p1 Int
    m1 (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    l1 IntMap b
    l2) (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    r1 IntMap b
    r2)
          | Bool
    otherwise      = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    p1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    p2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
          where
            merge1 :: IntMap c
    merge1 | Int -> Int -> Int -> Bool
    nomatch Int
    p2 Int
    p1 Int
    m1  = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    p1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    p2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
                   | Int -> Int -> Bool
    zero Int
    p2 Int
    m1        = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p1 Int
    m1 (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    l1 IntMap b
    t2) (IntMap a -> IntMap c
    g1 IntMap a
    r1)
                   | Bool
    otherwise         = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p1 Int
    m1 (IntMap a -> IntMap c
    g1 IntMap a
    l1) (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    r1 IntMap b
    t2)
            merge2 :: IntMap c
    merge2 | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2  = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    p1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    p2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
                   | Int -> Int -> Bool
    zero Int
    p1 Int
    m2        = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p2 Int
    m2 (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    t1 IntMap b
    l2) (IntMap b -> IntMap c
    g2 IntMap b
    r2)
                   | Bool
    otherwise         = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p2 Int
    m2 (IntMap b -> IntMap c
    g2 IntMap b
    l2) (IntMap a -> IntMap b -> IntMap c
    go IntMap a
    t1 IntMap b
    r2)

        go t1' :: IntMap a
    t1'@(Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) t2' :: IntMap b
    t2'@(Tip Int
    k2' b
    _) = IntMap b -> Int -> IntMap a -> IntMap c
    merge0 IntMap b
    t2' Int
    k2' IntMap a
    t1'
          where
            merge0 :: IntMap b -> Int -> IntMap a -> IntMap c
    merge0 IntMap b
    t2 Int
    k2 t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1)
              | Int -> Int -> Int -> Bool
    nomatch Int
    k2 Int
    p1 Int
    m1 = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    p1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    k2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
              | Int -> Int -> Bool
    zero Int
    k2 Int
    m1 = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p1 Int
    m1 (IntMap b -> Int -> IntMap a -> IntMap c
    merge0 IntMap b
    t2 Int
    k2 IntMap a
    l1) (IntMap a -> IntMap c
    g1 IntMap a
    r1)
              | Bool
    otherwise  = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p1 Int
    m1 (IntMap a -> IntMap c
    g1 IntMap a
    l1) (IntMap b -> Int -> IntMap a -> IntMap c
    merge0 IntMap b
    t2 Int
    k2 IntMap a
    r1)
            merge0 IntMap b
    t2 Int
    k2 t1 :: IntMap a
    t1@(Tip Int
    k1 a
    _)
              | Int
    k1 forall a. Eq a => a -> a -> Bool
    == Int
    k2 = IntMap a -> IntMap b -> IntMap c
    f IntMap a
    t1 IntMap b
    t2
              | Bool
    otherwise = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    k1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    k2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
            merge0 IntMap b
    t2 Int
    _  IntMap a
    Nil = IntMap b -> IntMap c
    g2 IntMap b
    t2

        go t1 :: IntMap a
    t1@(Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) IntMap b
    Nil = IntMap a -> IntMap c
    g1 IntMap a
    t1

        go t1' :: IntMap a
    t1'@(Tip Int
    k1' a
    _) IntMap b
    t2' = IntMap a -> Int -> IntMap b -> IntMap c
    merge0 IntMap a
    t1' Int
    k1' IntMap b
    t2'
          where
            merge0 :: IntMap a -> Int -> IntMap b -> IntMap c
    merge0 IntMap a
    t1 Int
    k1 t2 :: IntMap b
    t2@(Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
              | Int -> Int -> Int -> Bool
    nomatch Int
    k1 Int
    p2 Int
    m2 = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    k1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    p2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
              | Int -> Int -> Bool
    zero Int
    k1 Int
    m2 = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p2 Int
    m2 (IntMap a -> Int -> IntMap b -> IntMap c
    merge0 IntMap a
    t1 Int
    k1 IntMap b
    l2) (IntMap b -> IntMap c
    g2 IntMap b
    r2)
              | Bool
    otherwise  = Int -> Int -> IntMap c -> IntMap c -> IntMap c
    bin' Int
    p2 Int
    m2 (IntMap b -> IntMap c
    g2 IntMap b
    l2) (IntMap a -> Int -> IntMap b -> IntMap c
    merge0 IntMap a
    t1 Int
    k1 IntMap b
    r2)
            merge0 IntMap a
    t1 Int
    k1 t2 :: IntMap b
    t2@(Tip Int
    k2 b
    _)
              | Int
    k1 forall a. Eq a => a -> a -> Bool
    == Int
    k2 = IntMap a -> IntMap b -> IntMap c
    f IntMap a
    t1 IntMap b
    t2
              | Bool
    otherwise = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    k1 (IntMap a -> IntMap c
    g1 IntMap a
    t1) Int
    k2 (IntMap b -> IntMap c
    g2 IntMap b
    t2)
            merge0 IntMap a
    t1 Int
    _  IntMap b
    Nil = IntMap a -> IntMap c
    g1 IntMap a
    t1

        go IntMap a
    Nil IntMap b
    t2 = IntMap b -> IntMap c
    g2 IntMap b
    t2

        maybe_link :: Int -> IntMap a -> Int -> IntMap a -> IntMap a
    maybe_link Int
    _ IntMap a
    Nil Int
    _ IntMap a
    t2 = IntMap a
    t2
        maybe_link Int
    _ IntMap a
    t1 Int
    _ IntMap a
    Nil = IntMap a
    t1
        maybe_link Int
    p1 IntMap a
    t1 Int
    p2 IntMap a
    t2 = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    p1 IntMap a
    t1 Int
    p2 IntMap a
    t2
        {-# INLINE maybe_link #-}
    {-# INLINE mergeWithKey' #-}

    {--------------------------------------------------------------------
      mergeA
    --------------------------------------------------------------------}

    -- | A tactic for dealing with keys present in one map but not the
    -- other in 'merge' or 'mergeA'.
    --
    -- A tactic of type @WhenMissing f k x z@ is an abstract representation
    -- of a function of type @Key -> x -> f (Maybe z)@.
    --
    -- @since 0.5.9

    data WhenMissing f x y = WhenMissing
      { forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree :: IntMap x -> f (IntMap y)
      , forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey :: Key -> x -> f (Maybe y)}

    -- | @since 0.5.9
    instance (Applicative f, Monad f) => Functor (WhenMissing f x) where
      fmap :: forall a b. (a -> b) -> WhenMissing f x a -> WhenMissing f x b
    fmap = forall (f :: * -> *) a b x.
    (Applicative f, Monad f) =>
    (a -> b) -> WhenMissing f x a -> WhenMissing f x b
    mapWhenMissing
      {-# INLINE fmap #-}

    -- | @since 0.5.9
    instance (Applicative f, Monad f) => Category.Category (WhenMissing f)
      where
        id :: forall a. WhenMissing f a a
    id = forall (f :: * -> *) x. Applicative f => WhenMissing f x x
    preserveMissing
        WhenMissing f b c
    f . :: forall b c a.
    WhenMissing f b c -> WhenMissing f a b -> WhenMissing f a c
    . WhenMissing f a b
    g =
          forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> f (Maybe y)) -> WhenMissing f x y
    traverseMaybeMissing forall a b. (a -> b) -> a -> b
    $ \ Int
    k a
    x -> do
            Maybe b
    y <- forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f a b
    g Int
    k a
    x
            case Maybe b
    y of
              Maybe b
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
              Just b
    q  -> forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f b c
    f Int
    k b
    q
        {-# INLINE id #-}
        {-# INLINE (.) #-}

    -- | Equivalent to @ReaderT k (ReaderT x (MaybeT f))@.
    --
    -- @since 0.5.9
    instance (Applicative f, Monad f) => Applicative (WhenMissing f x) where
      pure :: forall a. a -> WhenMissing f x a
    pure a
    x = forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> y) -> WhenMissing f x y
    mapMissing (\ Int
    _ x
    _ -> a
    x)
      WhenMissing f x (a -> b)
    f <*> :: forall a b.
    WhenMissing f x (a -> b) -> WhenMissing f x a -> WhenMissing f x b
    <*> WhenMissing f x a
    g =
        forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> f (Maybe y)) -> WhenMissing f x y
    traverseMaybeMissing forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x -> do
          Maybe (a -> b)
    res1 <- forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f x (a -> b)
    f Int
    k x
    x
          case Maybe (a -> b)
    res1 of
            Maybe (a -> b)
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
            Just a -> b
    r  -> (forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $!) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    r forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f x a
    g Int
    k x
    x
      {-# INLINE pure #-}
      {-# INLINE (<*>) #-}

    -- | Equivalent to @ReaderT k (ReaderT x (MaybeT f))@.
    --
    -- @since 0.5.9
    instance (Applicative f, Monad f) => Monad (WhenMissing f x) where
    #if !MIN_VERSION_base(4,8,0)
      return = pure
    #endif
      WhenMissing f x a
    m >>= :: forall a b.
    WhenMissing f x a -> (a -> WhenMissing f x b) -> WhenMissing f x b
    >>= a -> WhenMissing f x b
    f =
        forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> f (Maybe y)) -> WhenMissing f x y
    traverseMaybeMissing forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x -> do
          Maybe a
    res1 <- forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f x a
    m Int
    k x
    x
          case Maybe a
    res1 of
            Maybe a
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
            Just a
    r  -> forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey (a -> WhenMissing f x b
    f a
    r) Int
    k x
    x
      {-# INLINE (>>=) #-}

    -- | Map covariantly over a @'WhenMissing' f x@.
    --
    -- @since 0.5.9
    mapWhenMissing
      :: (Applicative f, Monad f)
      => (a -> b)
      -> WhenMissing f x a
      -> WhenMissing f x b
    mapWhenMissing :: forall (f :: * -> *) a b x.
    (Applicative f, Monad f) =>
    (a -> b) -> WhenMissing f x a -> WhenMissing f x b
    mapWhenMissing a -> b
    f WhenMissing f x a
    t = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap b)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree WhenMissing f x a
    t IntMap x
    m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \IntMap a
    m' -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f IntMap a
    m'
      , missingKey :: Int -> x -> f (Maybe b)
    missingKey     = \Int
    k x
    x -> forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f x a
    t Int
    k x
    x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Maybe a
    q -> (forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f Maybe a
    q) }
    {-# INLINE mapWhenMissing #-}

    -- | Map covariantly over a @'WhenMissing' f x@, using only a
    -- 'Functor f' constraint.
    mapGentlyWhenMissing
      :: Functor f
      => (a -> b)
      -> WhenMissing f x a
      -> WhenMissing f x b
    mapGentlyWhenMissing :: forall (f :: * -> *) a b x.
    Functor f =>
    (a -> b) -> WhenMissing f x a -> WhenMissing f x b
    mapGentlyWhenMissing a -> b
    f WhenMissing f x a
    t = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap b)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree WhenMissing f x a
    t IntMap x
    m
      , missingKey :: Int -> x -> f (Maybe b)
    missingKey     = \Int
    k x
    x -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f x a
    t Int
    k x
    x }
    {-# INLINE mapGentlyWhenMissing #-}

    -- | Map covariantly over a @'WhenMatched' f k x@, using only a
    -- 'Functor f' constraint.
    mapGentlyWhenMatched
      :: Functor f
      => (a -> b)
      -> WhenMatched f x y a
      -> WhenMatched f x y b
    mapGentlyWhenMatched :: forall (f :: * -> *) a b x y.
    Functor f =>
    (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
    mapGentlyWhenMatched a -> b
    f WhenMatched f x y a
    t =
      forall x y (f :: * -> *) z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    zipWithMaybeAMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x y
    y -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x y a
    t Int
    k x
    x y
    y
    {-# INLINE mapGentlyWhenMatched #-}

    -- | Map contravariantly over a @'WhenMissing' f _ x@.
    --
    -- @since 0.5.9
    lmapWhenMissing :: (b -> a) -> WhenMissing f a x -> WhenMissing f b x
    lmapWhenMissing :: forall b a (f :: * -> *) x.
    (b -> a) -> WhenMissing f a x -> WhenMissing f b x
    lmapWhenMissing b -> a
    f WhenMissing f a x
    t = WhenMissing
      { missingSubtree :: IntMap b -> f (IntMap x)
    missingSubtree = \IntMap b
    m -> forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree WhenMissing f a x
    t (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap b -> a
    f IntMap b
    m)
      , missingKey :: Int -> b -> f (Maybe x)
    missingKey     = \Int
    k b
    x -> forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey WhenMissing f a x
    t Int
    k (b -> a
    f b
    x) }
    {-# INLINE lmapWhenMissing #-}

    -- | Map contravariantly over a @'WhenMatched' f _ y z@.
    --
    -- @since 0.5.9
    contramapFirstWhenMatched
      :: (b -> a)
      -> WhenMatched f a y z
      -> WhenMatched f b y z
    contramapFirstWhenMatched :: forall b a (f :: * -> *) y z.
    (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z
    contramapFirstWhenMatched b -> a
    f WhenMatched f a y z
    t =
      forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k b
    x y
    y -> forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f a y z
    t Int
    k (b -> a
    f b
    x) y
    y
    {-# INLINE contramapFirstWhenMatched #-}

    -- | Map contravariantly over a @'WhenMatched' f x _ z@.
    --
    -- @since 0.5.9
    contramapSecondWhenMatched
      :: (b -> a)
      -> WhenMatched f x a z
      -> WhenMatched f x b z
    contramapSecondWhenMatched :: forall b a (f :: * -> *) x z.
    (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z
    contramapSecondWhenMatched b -> a
    f WhenMatched f x a z
    t =
      forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x b
    y -> forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x a z
    t Int
    k x
    x (b -> a
    f b
    y)
    {-# INLINE contramapSecondWhenMatched #-}

    #if !MIN_VERSION_base(4,8,0)
    newtype Identity a = Identity {runIdentity :: a}

    instance Functor Identity where
        fmap f (Identity x) = Identity (f x)

    instance Applicative Identity where
        pure = Identity
        Identity f <*> Identity x = Identity (f x)
    #endif

    -- | A tactic for dealing with keys present in one map but not the
    -- other in 'merge'.
    --
    -- A tactic of type @SimpleWhenMissing x z@ is an abstract
    -- representation of a function of type @Key -> x -> Maybe z@.
    --
    -- @since 0.5.9
    type SimpleWhenMissing = WhenMissing Identity

    -- | A tactic for dealing with keys present in both maps in 'merge'
    -- or 'mergeA'.
    --
    -- A tactic of type @WhenMatched f x y z@ is an abstract representation
    -- of a function of type @Key -> x -> y -> f (Maybe z)@.
    --
    -- @since 0.5.9
    newtype WhenMatched f x y z = WhenMatched
      { forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    matchedKey :: Key -> x -> y -> f (Maybe z) }

    -- | Along with zipWithMaybeAMatched, witnesses the isomorphism
    -- between @WhenMatched f x y z@ and @Key -> x -> y -> f (Maybe z)@.
    --
    -- @since 0.5.9
    runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)
    runWhenMatched :: forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched = forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    matchedKey
    {-# INLINE runWhenMatched #-}

    -- | Along with traverseMaybeMissing, witnesses the isomorphism
    -- between @WhenMissing f x y@ and @Key -> x -> f (Maybe y)@.
    --
    -- @since 0.5.9
    runWhenMissing :: WhenMissing f x y -> Key-> x -> f (Maybe y)
    runWhenMissing :: forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    runWhenMissing = forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey
    {-# INLINE runWhenMissing #-}

    -- | @since 0.5.9
    instance Functor f => Functor (WhenMatched f x y) where
      fmap :: forall a b. (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
    fmap = forall (f :: * -> *) a b x y.
    Functor f =>
    (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
    mapWhenMatched
      {-# INLINE fmap #-}

    -- | @since 0.5.9
    instance (Monad f, Applicative f) => Category.Category (WhenMatched f x)
      where
        id :: forall a. WhenMatched f x a a
    id = forall (f :: * -> *) x y z.
    Applicative f =>
    (Int -> x -> y -> z) -> WhenMatched f x y z
    zipWithMatched (\Int
    _ x
    _ a
    y -> a
    y)
        WhenMatched f x b c
    f . :: forall b c a.
    WhenMatched f x b c -> WhenMatched f x a b -> WhenMatched f x a c
    . WhenMatched f x a b
    g =
          forall x y (f :: * -> *) z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    zipWithMaybeAMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x a
    y -> do
            Maybe b
    res <- forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x a b
    g Int
    k x
    x a
    y
            case Maybe b
    res of
              Maybe b
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
              Just b
    r  -> forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x b c
    f Int
    k x
    x b
    r
        {-# INLINE id #-}
        {-# INLINE (.) #-}

    -- | Equivalent to @ReaderT Key (ReaderT x (ReaderT y (MaybeT f)))@
    --
    -- @since 0.5.9
    instance (Monad f, Applicative f) => Applicative (WhenMatched f x y) where
      pure :: forall a. a -> WhenMatched f x y a
    pure a
    x = forall (f :: * -> *) x y z.
    Applicative f =>
    (Int -> x -> y -> z) -> WhenMatched f x y z
    zipWithMatched (\Int
    _ x
    _ y
    _ -> a
    x)
      WhenMatched f x y (a -> b)
    fs <*> :: forall a b.
    WhenMatched f x y (a -> b)
    -> WhenMatched f x y a -> WhenMatched f x y b
    <*> WhenMatched f x y a
    xs =
        forall x y (f :: * -> *) z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    zipWithMaybeAMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x y
    y -> do
          Maybe (a -> b)
    res <- forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x y (a -> b)
    fs Int
    k x
    x y
    y
          case Maybe (a -> b)
    res of
            Maybe (a -> b)
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
            Just a -> b
    r  -> (forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $!) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    r forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x y a
    xs Int
    k x
    x y
    y
      {-# INLINE pure #-}
      {-# INLINE (<*>) #-}

    -- | Equivalent to @ReaderT Key (ReaderT x (ReaderT y (MaybeT f)))@
    --
    -- @since 0.5.9
    instance (Monad f, Applicative f) => Monad (WhenMatched f x y) where
    #if !MIN_VERSION_base(4,8,0)
      return = pure
    #endif
      WhenMatched f x y a
    m >>= :: forall a b.
    WhenMatched f x y a
    -> (a -> WhenMatched f x y b) -> WhenMatched f x y b
    >>= a -> WhenMatched f x y b
    f =
        forall x y (f :: * -> *) z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    zipWithMaybeAMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x y
    y -> do
          Maybe a
    res <- forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched WhenMatched f x y a
    m Int
    k x
    x y
    y
          case Maybe a
    res of
            Maybe a
    Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing
            Just a
    r  -> forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    runWhenMatched (a -> WhenMatched f x y b
    f a
    r) Int
    k x
    x y
    y
      {-# INLINE (>>=) #-}

    -- | Map covariantly over a @'WhenMatched' f x y@.
    --
    -- @since 0.5.9
    mapWhenMatched
      :: Functor f
      => (a -> b)
      -> WhenMatched f x y a
      -> WhenMatched f x y b
    mapWhenMatched :: forall (f :: * -> *) a b x y.
    Functor f =>
    (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
    mapWhenMatched a -> b
    f (WhenMatched Int -> x -> y -> f (Maybe a)
    g) =
      forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \Int
    k x
    x y
    y -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) (Int -> x -> y -> f (Maybe a)
    g Int
    k x
    x y
    y)
    {-# INLINE mapWhenMatched #-}

    -- | A tactic for dealing with keys present in both maps in 'merge'.
    --
    -- A tactic of type @SimpleWhenMatched x y z@ is an abstract
    -- representation of a function of type @Key -> x -> y -> Maybe z@.
    --
    -- @since 0.5.9
    type SimpleWhenMatched = WhenMatched Identity

    -- | When a key is found in both maps, apply a function to the key
    -- and values and use the result in the merged map.
    --
    -- > zipWithMatched
    -- >   :: (Key -> x -> y -> z)
    -- >   -> SimpleWhenMatched x y z
    --
    -- @since 0.5.9
    zipWithMatched
      :: Applicative f
      => (Key -> x -> y -> z)
      -> WhenMatched f x y z
    zipWithMatched :: forall (f :: * -> *) x y z.
    Applicative f =>
    (Int -> x -> y -> z) -> WhenMatched f x y z
    zipWithMatched Int -> x -> y -> z
    f = forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \ Int
    k x
    x y
    y -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. a -> Maybe a
    Just forall a b. (a -> b) -> a -> b
    $ Int -> x -> y -> z
    f Int
    k x
    x y
    y
    {-# INLINE zipWithMatched #-}

    -- | When a key is found in both maps, apply a function to the key
    -- and values to produce an action and use its result in the merged
    -- map.
    --
    -- @since 0.5.9
    zipWithAMatched
      :: Applicative f
      => (Key -> x -> y -> f z)
      -> WhenMatched f x y z
    zipWithAMatched :: forall (f :: * -> *) x y z.
    Applicative f =>
    (Int -> x -> y -> f z) -> WhenMatched f x y z
    zipWithAMatched Int -> x -> y -> f z
    f = forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \ Int
    k x
    x y
    y -> forall a. a -> Maybe a
    Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> x -> y -> f z
    f Int
    k x
    x y
    y
    {-# INLINE zipWithAMatched #-}

    -- | When a key is found in both maps, apply a function to the key
    -- and values and maybe use the result in the merged map.
    --
    -- > zipWithMaybeMatched
    -- >   :: (Key -> x -> y -> Maybe z)
    -- >   -> SimpleWhenMatched x y z
    --
    -- @since 0.5.9
    zipWithMaybeMatched
      :: Applicative f
      => (Key -> x -> y -> Maybe z)
      -> WhenMatched f x y z
    zipWithMaybeMatched :: forall (f :: * -> *) x y z.
    Applicative f =>
    (Int -> x -> y -> Maybe z) -> WhenMatched f x y z
    zipWithMaybeMatched Int -> x -> y -> Maybe z
    f = forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \ Int
    k x
    x y
    y -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $ Int -> x -> y -> Maybe z
    f Int
    k x
    x y
    y
    {-# INLINE zipWithMaybeMatched #-}

    -- | When a key is found in both maps, apply a function to the key
    -- and values, perform the resulting action, and maybe use the
    -- result in the merged map.
    --
    -- This is the fundamental 'WhenMatched' tactic.
    --
    -- @since 0.5.9
    zipWithMaybeAMatched
      :: (Key -> x -> y -> f (Maybe z))
      -> WhenMatched f x y z
    zipWithMaybeAMatched :: forall x y (f :: * -> *) z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    zipWithMaybeAMatched Int -> x -> y -> f (Maybe z)
    f = forall (f :: * -> *) x y z.
    (Int -> x -> y -> f (Maybe z)) -> WhenMatched f x y z
    WhenMatched forall a b. (a -> b) -> a -> b
    $ \ Int
    k x
    x y
    y -> Int -> x -> y -> f (Maybe z)
    f Int
    k x
    x y
    y
    {-# INLINE zipWithMaybeAMatched #-}

    -- | Drop all the entries whose keys are missing from the other
    -- map.
    --
    -- > dropMissing :: SimpleWhenMissing x y
    --
    -- prop> dropMissing = mapMaybeMissing (\_ _ -> Nothing)
    --
    -- but @dropMissing@ is much faster.
    --
    -- @since 0.5.9
    dropMissing :: Applicative f => WhenMissing f x y
    dropMissing :: forall (f :: * -> *) x y. Applicative f => WhenMissing f x y
    dropMissing = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap y)
    missingSubtree = forall a b. a -> b -> a
    const (forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. IntMap a
    Nil)
      , missingKey :: Int -> x -> f (Maybe y)
    missingKey     = \Int
    _ x
    _ -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. Maybe a
    Nothing }
    {-# INLINE dropMissing #-}

    -- | Preserve, unchanged, the entries whose keys are missing from
    -- the other map.
    --
    -- > preserveMissing :: SimpleWhenMissing x x
    --
    -- prop> preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -> Just x)
    --
    -- but @preserveMissing@ is much faster.
    --
    -- @since 0.5.9
    preserveMissing :: Applicative f => WhenMissing f x x
    preserveMissing :: forall (f :: * -> *) x. Applicative f => WhenMissing f x x
    preserveMissing = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap x)
    missingSubtree = forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      , missingKey :: Int -> x -> f (Maybe x)
    missingKey     = \Int
    _ x
    v -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure (forall a. a -> Maybe a
    Just x
    v) }
    {-# INLINE preserveMissing #-}

    -- | Map over the entries whose keys are missing from the other map.
    --
    -- > mapMissing :: (k -> x -> y) -> SimpleWhenMissing x y
    --
    -- prop> mapMissing f = mapMaybeMissing (\k x -> Just $ f k x)
    --
    -- but @mapMissing@ is somewhat faster.
    --
    -- @since 0.5.9
    mapMissing :: Applicative f => (Key -> x -> y) -> WhenMissing f x y
    mapMissing :: forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> y) -> WhenMissing f x y
    mapMissing Int -> x -> y
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap y)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
    mapWithKey Int -> x -> y
    f IntMap x
    m
      , missingKey :: Int -> x -> f (Maybe y)
    missingKey     = \Int
    k x
    x -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $ forall a. a -> Maybe a
    Just (Int -> x -> y
    f Int
    k x
    x) }
    {-# INLINE mapMissing #-}

    -- | Map over the entries whose keys are missing from the other
    -- map, optionally removing some. This is the most powerful
    -- 'SimpleWhenMissing' tactic, but others are usually more efficient.
    --
    -- > mapMaybeMissing :: (Key -> x -> Maybe y) -> SimpleWhenMissing x y
    --
    -- prop> mapMaybeMissing f = traverseMaybeMissing (\k x -> pure (f k x))
    --
    -- but @mapMaybeMissing@ uses fewer unnecessary 'Applicative'
    -- operations.
    --
    -- @since 0.5.9
    mapMaybeMissing
      :: Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y
    mapMaybeMissing :: forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> Maybe y) -> WhenMissing f x y
    mapMaybeMissing Int -> x -> Maybe y
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap y)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey Int -> x -> Maybe y
    f IntMap x
    m
      , missingKey :: Int -> x -> f (Maybe y)
    missingKey     = \Int
    k x
    x -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! Int -> x -> Maybe y
    f Int
    k x
    x }
    {-# INLINE mapMaybeMissing #-}

    -- | Filter the entries whose keys are missing from the other map.
    --
    -- > filterMissing :: (k -> x -> Bool) -> SimpleWhenMissing x x
    --
    -- prop> filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -> guard (f k x) *> Just x
    --
    -- but this should be a little faster.
    --
    -- @since 0.5.9
    filterMissing
      :: Applicative f => (Key -> x -> Bool) -> WhenMissing f x x
    filterMissing :: forall (f :: * -> *) x.
    Applicative f =>
    (Int -> x -> Bool) -> WhenMissing f x x
    filterMissing Int -> x -> Bool
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap x)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
    filterWithKey Int -> x -> Bool
    f IntMap x
    m
      , missingKey :: Int -> x -> f (Maybe x)
    missingKey     = \Int
    k x
    x -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a b. (a -> b) -> a -> b
    $! if Int -> x -> Bool
    f Int
    k x
    x then forall a. a -> Maybe a
    Just x
    x else forall a. Maybe a
    Nothing }
    {-# INLINE filterMissing #-}

    -- | Filter the entries whose keys are missing from the other map
    -- using some 'Applicative' action.
    --
    -- > filterAMissing f = Merge.Lazy.traverseMaybeMissing $
    -- >   \k x -> (\b -> guard b *> Just x) <$> f k x
    --
    -- but this should be a little faster.
    --
    -- @since 0.5.9
    filterAMissing
      :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x
    filterAMissing :: forall (f :: * -> *) x.
    Applicative f =>
    (Int -> x -> f Bool) -> WhenMissing f x x
    filterAMissing Int -> x -> f Bool
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap x)
    missingSubtree = \IntMap x
    m -> forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> x -> f Bool
    f IntMap x
    m
      , missingKey :: Int -> x -> f (Maybe x)
    missingKey     = \Int
    k x
    x -> forall a. a -> a -> Bool -> a
    bool forall a. Maybe a
    Nothing (forall a. a -> Maybe a
    Just x
    x) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> x -> f Bool
    f Int
    k x
    x }
    {-# INLINE filterAMissing #-}

    -- | /O(n)/. Filter keys and values using an 'Applicative' predicate.
    filterWithKeyA
      :: Applicative f => (Key -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA :: forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> a -> f Bool
    _ IntMap a
    Nil           = forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. IntMap a
    Nil
    filterWithKeyA Int -> a -> f Bool
    f t :: IntMap a
    t@(Tip Int
    k a
    x)   = (\Bool
    b -> if Bool
    b then IntMap a
    t else forall a. IntMap a
    Nil) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> a -> f Bool
    f Int
    k a
    x
    filterWithKeyA Int -> a -> f Bool
    f (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a b c. (a -> b -> c) -> b -> a -> c
    flip (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m)) (forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> a -> f Bool
    f IntMap a
    r) (forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> a -> f Bool
    f IntMap a
    l)
      | Bool
    otherwise = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m) (forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> a -> f Bool
    f IntMap a
    l) (forall (f :: * -> *) a.
    Applicative f =>
    (Int -> a -> f Bool) -> IntMap a -> f (IntMap a)
    filterWithKeyA Int -> a -> f Bool
    f IntMap a
    r)

    -- | This wasn't in Data.Bool until 4.7.0, so we define it here
    bool :: a -> a -> Bool -> a
    bool :: forall a. a -> a -> Bool -> a
    bool a
    f a
    _ Bool
    False = a
    f
    bool a
    _ a
    t Bool
    True  = a
    t

    -- | Traverse over the entries whose keys are missing from the other
    -- map.
    --
    -- @since 0.5.9
    traverseMissing
      :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y
    traverseMissing :: forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> f y) -> WhenMissing f x y
    traverseMissing Int -> x -> f y
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap y)
    missingSubtree = forall (t :: * -> *) a b.
    Applicative t =>
    (Int -> a -> t b) -> IntMap a -> t (IntMap b)
    traverseWithKey Int -> x -> f y
    f
      , missingKey :: Int -> x -> f (Maybe y)
    missingKey = \Int
    k x
    x -> forall a. a -> Maybe a
    Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> x -> f y
    f Int
    k x
    x }
    {-# INLINE traverseMissing #-}

    -- | Traverse over the entries whose keys are missing from the other
    -- map, optionally producing values to put in the result. This is
    -- the most powerful 'WhenMissing' tactic, but others are usually
    -- more efficient.
    --
    -- @since 0.5.9
    traverseMaybeMissing
      :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y
    traverseMaybeMissing :: forall (f :: * -> *) x y.
    Applicative f =>
    (Int -> x -> f (Maybe y)) -> WhenMissing f x y
    traverseMaybeMissing Int -> x -> f (Maybe y)
    f = WhenMissing
      { missingSubtree :: IntMap x -> f (IntMap y)
    missingSubtree = forall (f :: * -> *) a b.
    Applicative f =>
    (Int -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)
    traverseMaybeWithKey Int -> x -> f (Maybe y)
    f
      , missingKey :: Int -> x -> f (Maybe y)
    missingKey = Int -> x -> f (Maybe y)
    f }
    {-# INLINE traverseMaybeMissing #-}

    -- | /O(n)/. Traverse keys\/values and collect the 'Just' results.
    --
    -- @since 0.6.4
    traverseMaybeWithKey
      :: Applicative f => (Key -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)
    traverseMaybeWithKey :: forall (f :: * -> *) a b.
    Applicative f =>
    (Int -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)
    traverseMaybeWithKey Int -> a -> f (Maybe b)
    f = IntMap a -> f (IntMap b)
    go
        where
        go :: IntMap a -> f (IntMap b)
    go IntMap a
    Nil           = forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. IntMap a
    Nil
        go (Tip Int
    k a
    x)     = forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. IntMap a
    Nil (forall a. Int -> a -> IntMap a
    Tip Int
    k) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> a -> f (Maybe b)
    f Int
    k a
    x
        go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a b c. (a -> b -> c) -> b -> a -> c
    flip (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m)) (IntMap a -> f (IntMap b)
    go IntMap a
    r) (IntMap a -> f (IntMap b)
    go IntMap a
    l)
          | Bool
    otherwise = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m) (IntMap a -> f (IntMap b)
    go IntMap a
    l) (IntMap a -> f (IntMap b)
    go IntMap a
    r)

    -- | Merge two maps.
    --
    -- 'merge' takes two 'WhenMissing' tactics, a 'WhenMatched' tactic
    -- and two maps. It uses the tactics to merge the maps. Its behavior
    -- is best understood via its fundamental tactics, 'mapMaybeMissing'
    -- and 'zipWithMaybeMatched'.
    --
    -- Consider
    --
    -- @
    -- merge (mapMaybeMissing g1)
    --              (mapMaybeMissing g2)
    --              (zipWithMaybeMatched f)
    --              m1 m2
    -- @
    --
    -- Take, for example,
    --
    -- @
    -- m1 = [(0, \'a\'), (1, \'b\'), (3, \'c\'), (4, \'d\')]
    -- m2 = [(1, "one"), (2, "two"), (4, "three")]
    -- @
    --
    -- 'merge' will first \"align\" these maps by key:
    --
    -- @
    -- m1 = [(0, \'a\'), (1, \'b\'),               (3, \'c\'), (4, \'d\')]
    -- m2 =           [(1, "one"), (2, "two"),           (4, "three")]
    -- @
    --
    -- It will then pass the individual entries and pairs of entries
    -- to @g1@, @g2@, or @f@ as appropriate:
    --
    -- @
    -- maybes = [g1 0 \'a\', f 1 \'b\' "one", g2 2 "two", g1 3 \'c\', f 4 \'d\' "three"]
    -- @
    --
    -- This produces a 'Maybe' for each key:
    --
    -- @
    -- keys =     0        1          2           3        4
    -- results = [Nothing, Just True, Just False, Nothing, Just True]
    -- @
    --
    -- Finally, the @Just@ results are collected into a map:
    --
    -- @
    -- return value = [(1, True), (2, False), (4, True)]
    -- @
    --
    -- The other tactics below are optimizations or simplifications of
    -- 'mapMaybeMissing' for special cases. Most importantly,
    --
    -- * 'dropMissing' drops all the keys.
    -- * 'preserveMissing' leaves all the entries alone.
    --
    -- When 'merge' is given three arguments, it is inlined at the call
    -- site. To prevent excessive inlining, you should typically use
    -- 'merge' to define your custom combining functions.
    --
    --
    -- Examples:
    --
    -- prop> unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
    -- prop> intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
    -- prop> differenceWith f = merge diffPreserve diffDrop f
    -- prop> symmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -> Nothing)
    -- prop> mapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
    --
    -- @since 0.5.9
    merge
      :: SimpleWhenMissing a c -- ^ What to do with keys in @m1@ but not @m2@
      -> SimpleWhenMissing b c -- ^ What to do with keys in @m2@ but not @m1@
      -> SimpleWhenMatched a b c -- ^ What to do with keys in both @m1@ and @m2@
      -> IntMap a -- ^ Map @m1@
      -> IntMap b -- ^ Map @m2@
      -> IntMap c
    merge :: forall a c b.
    SimpleWhenMissing a c
    -> SimpleWhenMissing b c
    -> SimpleWhenMatched a b c
    -> IntMap a
    -> IntMap b
    -> IntMap c
    merge SimpleWhenMissing a c
    g1 SimpleWhenMissing b c
    g2 SimpleWhenMatched a b c
    f IntMap a
    m1 IntMap b
    m2 =
      forall a. Identity a -> a
    runIdentity forall a b. (a -> b) -> a -> b
    $ forall (f :: * -> *) a c b.
    Applicative f =>
    WhenMissing f a c
    -> WhenMissing f b c
    -> WhenMatched f a b c
    -> IntMap a
    -> IntMap b
    -> f (IntMap c)
    mergeA SimpleWhenMissing a c
    g1 SimpleWhenMissing b c
    g2 SimpleWhenMatched a b c
    f IntMap a
    m1 IntMap b
    m2
    {-# INLINE merge #-}

    -- | An applicative version of 'merge'.
    --
    -- 'mergeA' takes two 'WhenMissing' tactics, a 'WhenMatched'
    -- tactic and two maps. It uses the tactics to merge the maps.
    -- Its behavior is best understood via its fundamental tactics,
    -- 'traverseMaybeMissing' and 'zipWithMaybeAMatched'.
    --
    -- Consider
    --
    -- @
    -- mergeA (traverseMaybeMissing g1)
    --               (traverseMaybeMissing g2)
    --               (zipWithMaybeAMatched f)
    --               m1 m2
    -- @
    --
    -- Take, for example,
    --
    -- @
    -- m1 = [(0, \'a\'), (1, \'b\'), (3,\'c\'), (4, \'d\')]
    -- m2 = [(1, "one"), (2, "two"), (4, "three")]
    -- @
    --
    -- 'mergeA' will first \"align\" these maps by key:
    --
    -- @
    -- m1 = [(0, \'a\'), (1, \'b\'),               (3, \'c\'), (4, \'d\')]
    -- m2 =           [(1, "one"), (2, "two"),           (4, "three")]
    -- @
    --
    -- It will then pass the individual entries and pairs of entries
    -- to @g1@, @g2@, or @f@ as appropriate:
    --
    -- @
    -- actions = [g1 0 \'a\', f 1 \'b\' "one", g2 2 "two", g1 3 \'c\', f 4 \'d\' "three"]
    -- @
    --
    -- Next, it will perform the actions in the @actions@ list in order from
    -- left to right.
    --
    -- @
    -- keys =     0        1          2           3        4
    -- results = [Nothing, Just True, Just False, Nothing, Just True]
    -- @
    --
    -- Finally, the @Just@ results are collected into a map:
    --
    -- @
    -- return value = [(1, True), (2, False), (4, True)]
    -- @
    --
    -- The other tactics below are optimizations or simplifications of
    -- 'traverseMaybeMissing' for special cases. Most importantly,
    --
    -- * 'dropMissing' drops all the keys.
    -- * 'preserveMissing' leaves all the entries alone.
    -- * 'mapMaybeMissing' does not use the 'Applicative' context.
    --
    -- When 'mergeA' is given three arguments, it is inlined at the call
    -- site. To prevent excessive inlining, you should generally only use
    -- 'mergeA' to define custom combining functions.
    --
    -- @since 0.5.9
    mergeA
      :: (Applicative f)
      => WhenMissing f a c -- ^ What to do with keys in @m1@ but not @m2@
      -> WhenMissing f b c -- ^ What to do with keys in @m2@ but not @m1@
      -> WhenMatched f a b c -- ^ What to do with keys in both @m1@ and @m2@
      -> IntMap a -- ^ Map @m1@
      -> IntMap b -- ^ Map @m2@
      -> f (IntMap c)
    mergeA :: forall (f :: * -> *) a c b.
    Applicative f =>
    WhenMissing f a c
    -> WhenMissing f b c
    -> WhenMatched f a b c
    -> IntMap a
    -> IntMap b
    -> f (IntMap c)
    mergeA
        WhenMissing{missingSubtree :: forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree = IntMap a -> f (IntMap c)
    g1t, missingKey :: forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey = Int -> a -> f (Maybe c)
    g1k}
        WhenMissing{missingSubtree :: forall (f :: * -> *) x y.
    WhenMissing f x y -> IntMap x -> f (IntMap y)
    missingSubtree = IntMap b -> f (IntMap c)
    g2t, missingKey :: forall (f :: * -> *) x y.
    WhenMissing f x y -> Int -> x -> f (Maybe y)
    missingKey = Int -> b -> f (Maybe c)
    g2k}
        WhenMatched{matchedKey :: forall (f :: * -> *) x y z.
    WhenMatched f x y z -> Int -> x -> y -> f (Maybe z)
    matchedKey = Int -> a -> b -> f (Maybe c)
    f}
        = IntMap a -> IntMap b -> f (IntMap c)
    go
      where
        go :: IntMap a -> IntMap b -> f (IntMap c)
    go IntMap a
    t1  IntMap b
    Nil = IntMap a -> f (IntMap c)
    g1t IntMap a
    t1
        go IntMap a
    Nil IntMap b
    t2  = IntMap b -> f (IntMap c)
    g2t IntMap b
    t2

        -- This case is already covered below.
        -- go (Tip k1 x1) (Tip k2 x2) = mergeTips k1 x1 k2 x2

        go (Tip Int
    k1 a
    x1) IntMap b
    t2' = IntMap b -> f (IntMap c)
    merge2 IntMap b
    t2'
          where
            merge2 :: IntMap b -> f (IntMap c)
    merge2 t2 :: IntMap b
    t2@(Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
              | Int -> Int -> Int -> Bool
    nomatch Int
    k1 Int
    p2 Int
    m2 = forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    k1 (forall {f :: * -> *} {t} {a}.
    Functor f =>
    (Int -> t -> f (Maybe a)) -> Int -> t -> f (IntMap a)
    subsingletonBy Int -> a -> f (Maybe c)
    g1k Int
    k1 a
    x1) Int
    p2 (IntMap b -> f (IntMap c)
    g2t IntMap b
    t2)
              | Int -> Int -> Bool
    zero Int
    k1 Int
    m2       = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p2 Int
    m2 (IntMap b -> f (IntMap c)
    merge2 IntMap b
    l2) (IntMap b -> f (IntMap c)
    g2t IntMap b
    r2)
              | Bool
    otherwise        = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p2 Int
    m2 (IntMap b -> f (IntMap c)
    g2t IntMap b
    l2) (IntMap b -> f (IntMap c)
    merge2 IntMap b
    r2)
            merge2 (Tip Int
    k2 b
    x2)   = Int -> a -> Int -> b -> f (IntMap c)
    mergeTips Int
    k1 a
    x1 Int
    k2 b
    x2
            merge2 IntMap b
    Nil           = forall {f :: * -> *} {t} {a}.
    Functor f =>
    (Int -> t -> f (Maybe a)) -> Int -> t -> f (IntMap a)
    subsingletonBy Int -> a -> f (Maybe c)
    g1k Int
    k1 a
    x1

        go IntMap a
    t1' (Tip Int
    k2 b
    x2) = IntMap a -> f (IntMap c)
    merge1 IntMap a
    t1'
          where
            merge1 :: IntMap a -> f (IntMap c)
    merge1 t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1)
              | Int -> Int -> Int -> Bool
    nomatch Int
    k2 Int
    p1 Int
    m1 = forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    p1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    t1) Int
    k2 (forall {f :: * -> *} {t} {a}.
    Functor f =>
    (Int -> t -> f (Maybe a)) -> Int -> t -> f (IntMap a)
    subsingletonBy Int -> b -> f (Maybe c)
    g2k Int
    k2 b
    x2)
              | Int -> Int -> Bool
    zero Int
    k2 Int
    m1       = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p1 Int
    m1 (IntMap a -> f (IntMap c)
    merge1 IntMap a
    l1) (IntMap a -> f (IntMap c)
    g1t IntMap a
    r1)
              | Bool
    otherwise        = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p1 Int
    m1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    l1) (IntMap a -> f (IntMap c)
    merge1 IntMap a
    r1)
            merge1 (Tip Int
    k1 a
    x1)   = Int -> a -> Int -> b -> f (IntMap c)
    mergeTips Int
    k1 a
    x1 Int
    k2 b
    x2
            merge1 IntMap a
    Nil           = forall {f :: * -> *} {t} {a}.
    Functor f =>
    (Int -> t -> f (Maybe a)) -> Int -> t -> f (IntMap a)
    subsingletonBy Int -> b -> f (Maybe c)
    g2k Int
    k2 b
    x2

        go t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) t2 :: IntMap b
    t2@(Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
          | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = f (IntMap c)
    merge1
          | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = f (IntMap c)
    merge2
          | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2       = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p1 Int
    m1 (IntMap a -> IntMap b -> f (IntMap c)
    go IntMap a
    l1 IntMap b
    l2) (IntMap a -> IntMap b -> f (IntMap c)
    go IntMap a
    r1 IntMap b
    r2)
          | Bool
    otherwise      = forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    p1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    t1) Int
    p2 (IntMap b -> f (IntMap c)
    g2t IntMap b
    t2)
          where
            merge1 :: f (IntMap c)
    merge1 | Int -> Int -> Int -> Bool
    nomatch Int
    p2 Int
    p1 Int
    m1  = forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    p1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    t1) Int
    p2 (IntMap b -> f (IntMap c)
    g2t IntMap b
    t2)
                   | Int -> Int -> Bool
    zero Int
    p2 Int
    m1        = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p1 Int
    m1 (IntMap a -> IntMap b -> f (IntMap c)
    go  IntMap a
    l1 IntMap b
    t2) (IntMap a -> f (IntMap c)
    g1t IntMap a
    r1)
                   | Bool
    otherwise         = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p1 Int
    m1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    l1)    (IntMap a -> IntMap b -> f (IntMap c)
    go  IntMap a
    r1 IntMap b
    t2)
            merge2 :: f (IntMap c)
    merge2 | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2  = forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    p1 (IntMap a -> f (IntMap c)
    g1t IntMap a
    t1) Int
    p2 (IntMap b -> f (IntMap c)
    g2t IntMap b
    t2)
                   | Int -> Int -> Bool
    zero Int
    p1 Int
    m2        = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p2 Int
    m2 (IntMap a -> IntMap b -> f (IntMap c)
    go  IntMap a
    t1 IntMap b
    l2) (IntMap b -> f (IntMap c)
    g2t    IntMap b
    r2)
                   | Bool
    otherwise         = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p2 Int
    m2 (IntMap b -> f (IntMap c)
    g2t    IntMap b
    l2) (IntMap a -> IntMap b -> f (IntMap c)
    go  IntMap a
    t1 IntMap b
    r2)

        subsingletonBy :: (Int -> t -> f (Maybe a)) -> Int -> t -> f (IntMap a)
    subsingletonBy Int -> t -> f (Maybe a)
    gk Int
    k t
    x = forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. IntMap a
    Nil (forall a. Int -> a -> IntMap a
    Tip Int
    k) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> t -> f (Maybe a)
    gk Int
    k t
    x
        {-# INLINE subsingletonBy #-}

        mergeTips :: Int -> a -> Int -> b -> f (IntMap c)
    mergeTips Int
    k1 a
    x1 Int
    k2 b
    x2
          | Int
    k1 forall a. Eq a => a -> a -> Bool
    == Int
    k2  = forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. IntMap a
    Nil (forall a. Int -> a -> IntMap a
    Tip Int
    k1) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> a -> b -> f (Maybe c)
    f Int
    k1 a
    x1 b
    x2
          | Int
    k1 forall a. Ord a => a -> a -> Bool
    <  Int
    k2  = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall {a}. Int -> Int -> Maybe a -> Maybe a -> IntMap a
    subdoubleton Int
    k1 Int
    k2) (Int -> a -> f (Maybe c)
    g1k Int
    k1 a
    x1) (Int -> b -> f (Maybe c)
    g2k Int
    k2 b
    x2)
            {-
            = link_ k1 k2 <$> subsingletonBy g1k k1 x1 <*> subsingletonBy g2k k2 x2
            -}
          | Bool
    otherwise = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall {a}. Int -> Int -> Maybe a -> Maybe a -> IntMap a
    subdoubleton Int
    k2 Int
    k1) (Int -> b -> f (Maybe c)
    g2k Int
    k2 b
    x2) (Int -> a -> f (Maybe c)
    g1k Int
    k1 a
    x1)
        {-# INLINE mergeTips #-}

        subdoubleton :: Int -> Int -> Maybe a -> Maybe a -> IntMap a
    subdoubleton Int
    _ Int
    _   Maybe a
    Nothing Maybe a
    Nothing     = forall a. IntMap a
    Nil
        subdoubleton Int
    _ Int
    k2  Maybe a
    Nothing (Just a
    y2)   = forall a. Int -> a -> IntMap a
    Tip Int
    k2 a
    y2
        subdoubleton Int
    k1 Int
    _  (Just a
    y1) Maybe a
    Nothing   = forall a. Int -> a -> IntMap a
    Tip Int
    k1 a
    y1
        subdoubleton Int
    k1 Int
    k2 (Just a
    y1) (Just a
    y2) = forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    k1 (forall a. Int -> a -> IntMap a
    Tip Int
    k1 a
    y1) Int
    k2 (forall a. Int -> a -> IntMap a
    Tip Int
    k2 a
    y2)
        {-# INLINE subdoubleton #-}

        -- | A variant of 'link_' which makes sure to execute side-effects
        -- in the right order.
        linkA
            :: Applicative f
            => Prefix -> f (IntMap a)
            -> Prefix -> f (IntMap a)
            -> f (IntMap a)
        linkA :: forall (f :: * -> *) a.
    Applicative f =>
    Int -> f (IntMap a) -> Int -> f (IntMap a) -> f (IntMap a)
    linkA Int
    p1 f (IntMap a)
    t1 Int
    p2 f (IntMap a)
    t2
          | Int -> Int -> Bool
    zero Int
    p1 Int
    m = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p Int
    m f (IntMap a)
    t1 f (IntMap a)
    t2
          | Bool
    otherwise = forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p Int
    m f (IntMap a)
    t2 f (IntMap a)
    t1
          where
            m :: Int
    m = Int -> Int -> Int
    branchMask Int
    p1 Int
    p2
            p :: Int
    p = Int -> Int -> Int
    mask Int
    p1 Int
    m
        {-# INLINE linkA #-}

        -- A variant of 'bin' that ensures that effects for negative keys are executed
        -- first.
        binA
            :: Applicative f
            => Prefix
            -> Mask
            -> f (IntMap a)
            -> f (IntMap a)
            -> f (IntMap a)
        binA :: forall (f :: * -> *) a.
    Applicative f =>
    Int -> Int -> f (IntMap a) -> f (IntMap a) -> f (IntMap a)
    binA Int
    p Int
    m f (IntMap a)
    a f (IntMap a)
    b
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a b c. (a -> b -> c) -> b -> a -> c
    flip (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m)) f (IntMap a)
    b f (IntMap a)
    a
          | Bool
    otherwise = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2       (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m)  f (IntMap a)
    a f (IntMap a)
    b
        {-# INLINE binA #-}
    {-# INLINE mergeA #-}

    {--------------------------------------------------------------------
      Min\/Max
    --------------------------------------------------------------------}

    -- | /O(min(n,W))/. Update the value at the minimal key.
    --
    -- > updateMinWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
    -- > updateMinWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"

    updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMinWithKey :: forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMinWithKey Int -> a -> Maybe a
    f IntMap a
    t =
      case IntMap a
    t of Bin Int
    p Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l (forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    go Int -> a -> Maybe a
    f IntMap a
    r)
                IntMap a
    _ -> forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    go Int -> a -> Maybe a
    f IntMap a
    t
      where
        go :: (Int -> t -> Maybe t) -> IntMap t -> IntMap t
    go Int -> t -> Maybe t
    f' (Bin Int
    p Int
    m IntMap t
    l IntMap t
    r) = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m ((Int -> t -> Maybe t) -> IntMap t -> IntMap t
    go Int -> t -> Maybe t
    f' IntMap t
    l) IntMap t
    r
        go Int -> t -> Maybe t
    f' (Tip Int
    k t
    y) = case Int -> t -> Maybe t
    f' Int
    k t
    y of
                            Just t
    y' -> forall a. Int -> a -> IntMap a
    Tip Int
    k t
    y'
                            Maybe t
    Nothing -> forall a. IntMap a
    Nil
        go Int -> t -> Maybe t
    _ IntMap t
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "updateMinWithKey Nil"

    -- | /O(min(n,W))/. Update the value at the maximal key.
    --
    -- > updateMaxWithKey (\ k a -> Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
    -- > updateMaxWithKey (\ _ _ -> Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"

    updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMaxWithKey :: forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMaxWithKey Int -> a -> Maybe a
    f IntMap a
    t =
      case IntMap a
    t of Bin Int
    p Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m (forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    go Int -> a -> Maybe a
    f IntMap a
    l) IntMap a
    r
                IntMap a
    _ -> forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    go Int -> a -> Maybe a
    f IntMap a
    t
      where
        go :: (Int -> t -> Maybe t) -> IntMap t -> IntMap t
    go Int -> t -> Maybe t
    f' (Bin Int
    p Int
    m IntMap t
    l IntMap t
    r) = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap t
    l ((Int -> t -> Maybe t) -> IntMap t -> IntMap t
    go Int -> t -> Maybe t
    f' IntMap t
    r)
        go Int -> t -> Maybe t
    f' (Tip Int
    k t
    y) = case Int -> t -> Maybe t
    f' Int
    k t
    y of
                            Just t
    y' -> forall a. Int -> a -> IntMap a
    Tip Int
    k t
    y'
                            Maybe t
    Nothing -> forall a. IntMap a
    Nil
        go Int -> t -> Maybe t
    _ IntMap t
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "updateMaxWithKey Nil"

    data View a = View {-# UNPACK #-} !Key a !(IntMap a)

    -- | /O(min(n,W))/. Retrieves the maximal (key,value) pair of the map, and
    -- the map stripped of that element, or 'Nothing' if passed an empty map.
    --
    -- > maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
    -- > maxViewWithKey empty == Nothing

    maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)
    maxViewWithKey :: forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    maxViewWithKey IntMap a
    t = case IntMap a
    t of
      IntMap a
    Nil -> forall a. Maybe a
    Nothing
      IntMap a
    _ -> forall a. a -> Maybe a
    Just forall a b. (a -> b) -> a -> b
    $ case forall a. IntMap a -> View a
    maxViewWithKeySure IntMap a
    t of
                    View Int
    k a
    v IntMap a
    t' -> ((Int
    k, a
    v), IntMap a
    t')
    {-# INLINE maxViewWithKey #-}

    maxViewWithKeySure :: IntMap a -> View a
    maxViewWithKeySure :: forall a. IntMap a -> View a
    maxViewWithKeySure IntMap a
    t =
      case IntMap a
    t of
        IntMap a
    Nil -> forall a. HasCallStack => [Char] -> a
    error [Char]
    "maxViewWithKeySure Nil"
        Bin Int
    p Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
          case forall a. IntMap a -> View a
    go IntMap a
    l of View Int
    k a
    a IntMap a
    l' -> forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    a (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m IntMap a
    l' IntMap a
    r)
        IntMap a
    _ -> forall a. IntMap a -> View a
    go IntMap a
    t
      where
        go :: IntMap a -> View a
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) =
            case IntMap a -> View a
    go IntMap a
    r of View Int
    k a
    a IntMap a
    r' -> forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    a (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l IntMap a
    r')
        go (Tip Int
    k a
    y) = forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    y forall a. IntMap a
    Nil
        go IntMap a
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "maxViewWithKey_go Nil"
    -- See note on NOINLINE at minViewWithKeySure
    {-# NOINLINE maxViewWithKeySure #-}

    -- | /O(min(n,W))/. Retrieves the minimal (key,value) pair of the map, and
    -- the map stripped of that element, or 'Nothing' if passed an empty map.
    --
    -- > minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
    -- > minViewWithKey empty == Nothing

    minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)
    minViewWithKey :: forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    minViewWithKey IntMap a
    t =
      case IntMap a
    t of
        IntMap a
    Nil -> forall a. Maybe a
    Nothing
        IntMap a
    _ -> forall a. a -> Maybe a
    Just forall a b. (a -> b) -> a -> b
    $ case forall a. IntMap a -> View a
    minViewWithKeySure IntMap a
    t of
                      View Int
    k a
    v IntMap a
    t' -> ((Int
    k, a
    v), IntMap a
    t')
    -- We inline this to give GHC the best possible chance of
    -- getting rid of the Maybe, pair, and Int constructors, as
    -- well as a thunk under the Just. That is, we really want to
    -- be certain this inlines!
    {-# INLINE minViewWithKey #-}

    minViewWithKeySure :: IntMap a -> View a
    minViewWithKeySure :: forall a. IntMap a -> View a
    minViewWithKeySure IntMap a
    t =
      case IntMap a
    t of
        IntMap a
    Nil -> forall a. HasCallStack => [Char] -> a
    error [Char]
    "minViewWithKeySure Nil"
        Bin Int
    p Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
          case forall a. IntMap a -> View a
    go IntMap a
    r of
            View Int
    k a
    a IntMap a
    r' -> forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    a (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    p Int
    m IntMap a
    l IntMap a
    r')
        IntMap a
    _ -> forall a. IntMap a -> View a
    go IntMap a
    t
      where
        go :: IntMap a -> View a
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) =
            case IntMap a -> View a
    go IntMap a
    l of View Int
    k a
    a IntMap a
    l' -> forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    a (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    p Int
    m IntMap a
    l' IntMap a
    r)
        go (Tip Int
    k a
    y) = forall a. Int -> a -> IntMap a -> View a
    View Int
    k a
    y forall a. IntMap a
    Nil
        go IntMap a
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "minViewWithKey_go Nil"
    -- There's never anything significant to be gained by inlining
    -- this. Sufficiently recent GHC versions will inline the wrapper
    -- anyway, which should be good enough.
    {-# NOINLINE minViewWithKeySure #-}

    -- | /O(min(n,W))/. Update the value at the maximal key.
    --
    -- > updateMax (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
    -- > updateMax (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"

    updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a
    updateMax :: forall a. (a -> Maybe a) -> IntMap a -> IntMap a
    updateMax a -> Maybe a
    f = forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMaxWithKey (forall a b. a -> b -> a
    const a -> Maybe a
    f)

    -- | /O(min(n,W))/. Update the value at the minimal key.
    --
    -- > updateMin (\ a -> Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
    -- > updateMin (\ _ -> Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"

    updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a
    updateMin :: forall a. (a -> Maybe a) -> IntMap a -> IntMap a
    updateMin a -> Maybe a
    f = forall a. (Int -> a -> Maybe a) -> IntMap a -> IntMap a
    updateMinWithKey (forall a b. a -> b -> a
    const a -> Maybe a
    f)

    -- | /O(min(n,W))/. Retrieves the maximal key of the map, and the map
    -- stripped of that element, or 'Nothing' if passed an empty map.
    maxView :: IntMap a -> Maybe (a, IntMap a)
    maxView :: forall a. IntMap a -> Maybe (a, IntMap a)
    maxView IntMap a
    t = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\((Int
    _, a
    x), IntMap a
    t') -> (a
    x, IntMap a
    t')) (forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    maxViewWithKey IntMap a
    t)

    -- | /O(min(n,W))/. Retrieves the minimal key of the map, and the map
    -- stripped of that element, or 'Nothing' if passed an empty map.
    minView :: IntMap a -> Maybe (a, IntMap a)
    minView :: forall a. IntMap a -> Maybe (a, IntMap a)
    minView IntMap a
    t = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\((Int
    _, a
    x), IntMap a
    t') -> (a
    x, IntMap a
    t')) (forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    minViewWithKey IntMap a
    t)

    -- | /O(min(n,W))/. Delete and find the maximal element.
    -- This function throws an error if the map is empty. Use 'maxViewWithKey'
    -- if the map may be empty.
    deleteFindMax :: IntMap a -> ((Key, a), IntMap a)
    deleteFindMax :: forall a. IntMap a -> ((Int, a), IntMap a)
    deleteFindMax = forall a. a -> Maybe a -> a
    fromMaybe (forall a. HasCallStack => [Char] -> a
    error [Char]
    "deleteFindMax: empty map has no maximal element") forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    maxViewWithKey

    -- | /O(min(n,W))/. Delete and find the minimal element.
    -- This function throws an error if the map is empty. Use 'minViewWithKey'
    -- if the map may be empty.
    deleteFindMin :: IntMap a -> ((Key, a), IntMap a)
    deleteFindMin :: forall a. IntMap a -> ((Int, a), IntMap a)
    deleteFindMin = forall a. a -> Maybe a -> a
    fromMaybe (forall a. HasCallStack => [Char] -> a
    error [Char]
    "deleteFindMin: empty map has no minimal element") forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. IntMap a -> Maybe ((Int, a), IntMap a)
    minViewWithKey

    -- | /O(min(n,W))/. The minimal key of the map. Returns 'Nothing' if the map is empty.
    lookupMin :: IntMap a -> Maybe (Key, a)
    lookupMin :: forall a. IntMap a -> Maybe (Int, a)
    lookupMin IntMap a
    Nil = forall a. Maybe a
    Nothing
    lookupMin (Tip Int
    k a
    v) = forall a. a -> Maybe a
    Just (Int
    k,a
    v)
    lookupMin (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
      | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall a. IntMap a -> Maybe (Int, a)
    go IntMap a
    r
      | Bool
    otherwise = forall a. IntMap a -> Maybe (Int, a)
    go IntMap a
    l
        where go :: IntMap b -> Maybe (Int, b)
    go (Tip Int
    k b
    v)      = forall a. a -> Maybe a
    Just (Int
    k,b
    v)
              go (Bin Int
    _ Int
    _ IntMap b
    l' IntMap b
    _) = IntMap b -> Maybe (Int, b)
    go IntMap b
    l'
              go IntMap b
    Nil            = forall a. Maybe a
    Nothing

    -- | /O(min(n,W))/. The minimal key of the map. Calls 'error' if the map is empty.
    -- Use 'minViewWithKey' if the map may be empty.
    findMin :: IntMap a -> (Key, a)
    findMin :: forall a. IntMap a -> (Int, a)
    findMin IntMap a
    t
      | Just (Int, a)
    r <- forall a. IntMap a -> Maybe (Int, a)
    lookupMin IntMap a
    t = (Int, a)
    r
      | Bool
    otherwise = forall a. HasCallStack => [Char] -> a
    error [Char]
    "findMin: empty map has no minimal element"

    -- | /O(min(n,W))/. The maximal key of the map. Returns 'Nothing' if the map is empty.
    lookupMax :: IntMap a -> Maybe (Key, a)
    lookupMax :: forall a. IntMap a -> Maybe (Int, a)
    lookupMax IntMap a
    Nil = forall a. Maybe a
    Nothing
    lookupMax (Tip Int
    k a
    v) = forall a. a -> Maybe a
    Just (Int
    k,a
    v)
    lookupMax (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
      | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall a. IntMap a -> Maybe (Int, a)
    go IntMap a
    l
      | Bool
    otherwise = forall a. IntMap a -> Maybe (Int, a)
    go IntMap a
    r
        where go :: IntMap b -> Maybe (Int, b)
    go (Tip Int
    k b
    v)      = forall a. a -> Maybe a
    Just (Int
    k,b
    v)
              go (Bin Int
    _ Int
    _ IntMap b
    _ IntMap b
    r') = IntMap b -> Maybe (Int, b)
    go IntMap b
    r'
              go IntMap b
    Nil            = forall a. Maybe a
    Nothing

    -- | /O(min(n,W))/. The maximal key of the map. Calls 'error' if the map is empty.
    -- Use 'maxViewWithKey' if the map may be empty.
    findMax :: IntMap a -> (Key, a)
    findMax :: forall a. IntMap a -> (Int, a)
    findMax IntMap a
    t
      | Just (Int, a)
    r <- forall a. IntMap a -> Maybe (Int, a)
    lookupMax IntMap a
    t = (Int, a)
    r
      | Bool
    otherwise = forall a. HasCallStack => [Char] -> a
    error [Char]
    "findMax: empty map has no maximal element"

    -- | /O(min(n,W))/. Delete the minimal key. Returns an empty map if the map is empty.
    --
    -- Note that this is a change of behaviour for consistency with 'Data.Map.Map' &#8211;
    -- versions prior to 0.5 threw an error if the 'IntMap' was already empty.
    deleteMin :: IntMap a -> IntMap a
    deleteMin :: forall a. IntMap a -> IntMap a
    deleteMin = forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. IntMap a
    Nil forall a b. (a, b) -> b
    snd forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. IntMap a -> Maybe (a, IntMap a)
    minView

    -- | /O(min(n,W))/. Delete the maximal key. Returns an empty map if the map is empty.
    --
    -- Note that this is a change of behaviour for consistency with 'Data.Map.Map' &#8211;
    -- versions prior to 0.5 threw an error if the 'IntMap' was already empty.
    deleteMax :: IntMap a -> IntMap a
    deleteMax :: forall a. IntMap a -> IntMap a
    deleteMax = forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. IntMap a
    Nil forall a b. (a, b) -> b
    snd forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. IntMap a -> Maybe (a, IntMap a)
    maxView

    {--------------------------------------------------------------------
      Submap
    --------------------------------------------------------------------}
    -- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
    -- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).
    isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool
    isProperSubmapOf :: forall a. Eq a => IntMap a -> IntMap a -> Bool
    isProperSubmapOf IntMap a
    m1 IntMap a
    m2
      = forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isProperSubmapOfBy forall a. Eq a => a -> a -> Bool
    (==) IntMap a
    m1 IntMap a
    m2

    {- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
     The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when
     @keys m1@ and @keys m2@ are not equal,
     all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
     applied to their respective values. For example, the following
     expressions are all 'True':

      > isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
      > isProperSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])

     But the following are all 'False':

      > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
      > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
      > isProperSubmapOfBy (<)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
    -}
    isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isProperSubmapOfBy :: forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isProperSubmapOfBy a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    t2
      = case forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    t2 of
          Ordering
    LT -> Bool
    True
          Ordering
    _  -> Bool
    False

    submapCmp :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp :: forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) (Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
      | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = Ordering
    GT
      | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = Ordering
    submapCmpLt
      | Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2       = Ordering
    submapCmpEq
      | Bool
    otherwise      = Ordering
    GT  -- disjoint
      where
        submapCmpLt :: Ordering
    submapCmpLt | Int -> Int -> Int -> Bool
    nomatch Int
    p1 Int
    p2 Int
    m2  = Ordering
    GT
                    | Int -> Int -> Bool
    zero Int
    p1 Int
    m2        = forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    l2
                    | Bool
    otherwise         = forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    r2
        submapCmpEq :: Ordering
    submapCmpEq = case (forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate IntMap a
    l1 IntMap b
    l2, forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Ordering
    submapCmp a -> b -> Bool
    predicate IntMap a
    r1 IntMap b
    r2) of
                        (Ordering
    GT,Ordering
    _ ) -> Ordering
    GT
                        (Ordering
    _ ,Ordering
    GT) -> Ordering
    GT
                        (Ordering
    EQ,Ordering
    EQ) -> Ordering
    EQ
                        (Ordering, Ordering)
    _       -> Ordering
    LT

    submapCmp a -> b -> Bool
    _         (Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) IntMap b
    _  = Ordering
    GT
    submapCmp a -> b -> Bool
    predicate (Tip Int
    kx a
    x) (Tip Int
    ky b
    y)
      | (Int
    kx forall a. Eq a => a -> a -> Bool
    == Int
    ky) Bool -> Bool -> Bool
    && a -> b -> Bool
    predicate a
    x b
    y = Ordering
    EQ
      | Bool
    otherwise                   = Ordering
    GT  -- disjoint
    submapCmp a -> b -> Bool
    predicate (Tip Int
    k a
    x) IntMap b
    t
      = case forall a. Int -> IntMap a -> Maybe a
    lookup Int
    k IntMap b
    t of
         Just b
    y | a -> b -> Bool
    predicate a
    x b
    y -> Ordering
    LT
         Maybe b
    _                      -> Ordering
    GT -- disjoint
    submapCmp a -> b -> Bool
    _    IntMap a
    Nil IntMap b
    Nil = Ordering
    EQ
    submapCmp a -> b -> Bool
    _    IntMap a
    Nil IntMap b
    _   = Ordering
    LT

    -- | /O(n+m)/. Is this a submap?
    -- Defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).
    isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool
    isSubmapOf :: forall a. Eq a => IntMap a -> IntMap a -> Bool
    isSubmapOf IntMap a
    m1 IntMap a
    m2
      = forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy forall a. Eq a => a -> a -> Bool
    (==) IntMap a
    m1 IntMap a
    m2

    {- | /O(n+m)/.
     The expression (@'isSubmapOfBy' f m1 m2@) returns 'True' if
     all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
     applied to their respective values. For example, the following
     expressions are all 'True':

      > isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
      > isSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
      > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])

     But the following are all 'False':

      > isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
      > isSubmapOfBy (<) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
      > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
    -}
    isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy :: forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy a -> b -> Bool
    predicate t1 :: IntMap a
    t1@(Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) (Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
      | Int -> Int -> Bool
    shorter Int
    m1 Int
    m2  = Bool
    False
      | Int -> Int -> Bool
    shorter Int
    m2 Int
    m1  = Int -> Int -> Int -> Bool
    match Int
    p1 Int
    p2 Int
    m2 Bool -> Bool -> Bool
    &&
                           if Int -> Int -> Bool
    zero Int
    p1 Int
    m2
                           then forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    l2
                           else forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy a -> b -> Bool
    predicate IntMap a
    t1 IntMap b
    r2
      | Bool
    otherwise      = (Int
    p1forall a. Eq a => a -> a -> Bool
    ==Int
    p2) Bool -> Bool -> Bool
    && forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy a -> b -> Bool
    predicate IntMap a
    l1 IntMap b
    l2 Bool -> Bool -> Bool
    && forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    isSubmapOfBy a -> b -> Bool
    predicate IntMap a
    r1 IntMap b
    r2
    isSubmapOfBy a -> b -> Bool
    _         (Bin Int
    _ Int
    _ IntMap a
    _ IntMap a
    _) IntMap b
    _ = Bool
    False
    isSubmapOfBy a -> b -> Bool
    predicate (Tip Int
    k a
    x) IntMap b
    t     = case forall a. Int -> IntMap a -> Maybe a
    lookup Int
    k IntMap b
    t of
                                             Just b
    y  -> a -> b -> Bool
    predicate a
    x b
    y
                                             Maybe b
    Nothing -> Bool
    False
    isSubmapOfBy a -> b -> Bool
    _         IntMap a
    Nil IntMap b
    _           = Bool
    True

    {--------------------------------------------------------------------
      Mapping
    --------------------------------------------------------------------}
    -- | /O(n)/. Map a function over all values in the map.
    --
    -- > map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]

    map :: (a -> b) -> IntMap a -> IntMap b
    map :: forall a b. (a -> b) -> IntMap a -> IntMap b
    map a -> b
    f = IntMap a -> IntMap b
    go
      where
        go :: IntMap a -> IntMap b
    go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (IntMap a -> IntMap b
    go IntMap a
    l) (IntMap a -> IntMap b
    go IntMap a
    r)
        go (Tip Int
    k a
    x)     = forall a. Int -> a -> IntMap a
    Tip Int
    k (a -> b
    f a
    x)
        go IntMap a
    Nil           = forall a. IntMap a
    Nil

    #ifdef __GLASGOW_HASKELL__
    {-# NOINLINE [1] map #-}
    {-# RULES
    "map/map" forall f g xs . map f (map g xs) = map (f . g) xs
     #-}
    #endif
    #if __GLASGOW_HASKELL__ >= 709
    -- Safe coercions were introduced in 7.8, but did not play well with RULES yet.
    {-# RULES
    "map/coerce" map coerce = coerce
     #-}
    #endif

    -- | /O(n)/. Map a function over all values in the map.
    --
    -- > let f key x = (show key) ++ ":" ++ x
    -- > mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]

    mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b
    mapWithKey :: forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
    mapWithKey Int -> a -> b
    f IntMap a
    t
      = case IntMap a
    t of
          Bin Int
    p Int
    m IntMap a
    l IntMap a
    r -> forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
    mapWithKey Int -> a -> b
    f IntMap a
    l) (forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
    mapWithKey Int -> a -> b
    f IntMap a
    r)
          Tip Int
    k a
    x     -> forall a. Int -> a -> IntMap a
    Tip Int
    k (Int -> a -> b
    f Int
    k a
    x)
          IntMap a
    Nil         -> forall a. IntMap a
    Nil

    #ifdef __GLASGOW_HASKELL__
    {-# NOINLINE [1] mapWithKey #-}
    {-# RULES
    "mapWithKey/mapWithKey" forall f g xs . mapWithKey f (mapWithKey g xs) =
      mapWithKey (\k a -> f k (g k a)) xs
    "mapWithKey/map" forall f g xs . mapWithKey f (map g xs) =
      mapWithKey (\k a -> f k (g a)) xs
    "map/mapWithKey" forall f g xs . map f (mapWithKey g xs) =
      mapWithKey (\k a -> f (g k a)) xs
     #-}
    #endif

    -- | /O(n)/.
    -- @'traverseWithKey' f s == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@
    -- That is, behaves exactly like a regular 'traverse' except that the traversing
    -- function also has access to the key associated with a value.
    --
    -- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
    -- > traverseWithKey (\k v -> if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
    traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)
    traverseWithKey :: forall (t :: * -> *) a b.
    Applicative t =>
    (Int -> a -> t b) -> IntMap a -> t (IntMap b)
    traverseWithKey Int -> a -> t b
    f = IntMap a -> t (IntMap b)
    go
      where
        go :: IntMap a -> t (IntMap b)
    go IntMap a
    Nil = forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall a. IntMap a
    Nil
        go (Tip Int
    k a
    v) = forall a. Int -> a -> IntMap a
    Tip Int
    k forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> a -> t b
    f Int
    k a
    v
        go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a b c. (a -> b -> c) -> b -> a -> c
    flip (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m)) (IntMap a -> t (IntMap b)
    go IntMap a
    r) (IntMap a -> t (IntMap b)
    go IntMap a
    l)
          | Bool
    otherwise = forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m) (IntMap a -> t (IntMap b)
    go IntMap a
    l) (IntMap a -> t (IntMap b)
    go IntMap a
    r)
    {-# INLINE traverseWithKey #-}

    -- | /O(n)/. The function @'mapAccum'@ threads an accumulating
    -- argument through the map in ascending order of keys.
    --
    -- > let f a b = (a ++ b, b ++ "X")
    -- > mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])

    mapAccum :: (a -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
    mapAccum :: forall a b c. (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccum a -> b -> (a, c)
    f = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumWithKey (\a
    a' Int
    _ b
    x -> a -> b -> (a, c)
    f a
    a' b
    x)

    -- | /O(n)/. The function @'mapAccumWithKey'@ threads an accumulating
    -- argument through the map in ascending order of keys.
    --
    -- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
    -- > mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])

    mapAccumWithKey :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
    mapAccumWithKey :: forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumWithKey a -> Int -> b -> (a, c)
    f a
    a IntMap b
    t
      = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a IntMap b
    t

    -- | /O(n)/. The function @'mapAccumL'@ threads an accumulating
    -- argument through the map in ascending order of keys.
    mapAccumL :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
    mapAccumL :: forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a IntMap b
    t
      = case IntMap b
    t of
          Bin Int
    p Int
    m IntMap b
    l IntMap b
    r
            | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
                let (a
    a1,IntMap c
    r') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a IntMap b
    r
                    (a
    a2,IntMap c
    l') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a1 IntMap b
    l
                in (a
    a2,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap c
    l' IntMap c
    r')
            | Bool
    otherwise  ->
                let (a
    a1,IntMap c
    l') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a IntMap b
    l
                    (a
    a2,IntMap c
    r') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumL a -> Int -> b -> (a, c)
    f a
    a1 IntMap b
    r
                in (a
    a2,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap c
    l' IntMap c
    r')
          Tip Int
    k b
    x     -> let (a
    a',c
    x') = a -> Int -> b -> (a, c)
    f a
    a Int
    k b
    x in (a
    a',forall a. Int -> a -> IntMap a
    Tip Int
    k c
    x')
          IntMap b
    Nil         -> (a
    a,forall a. IntMap a
    Nil)

    -- | /O(n)/. The function @'mapAccumRWithKey'@ threads an accumulating
    -- argument through the map in descending order of keys.
    mapAccumRWithKey :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
    mapAccumRWithKey :: forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumRWithKey a -> Int -> b -> (a, c)
    f a
    a IntMap b
    t
      = case IntMap b
    t of
          Bin Int
    p Int
    m IntMap b
    l IntMap b
    r
            | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
                let (a
    a1,IntMap c
    l') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumRWithKey a -> Int -> b -> (a, c)
    f a
    a IntMap b
    l
                    (a
    a2,IntMap c
    r') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumRWithKey a -> Int -> b -> (a, c)
    f a
    a1 IntMap b
    r
                in (a
    a2,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap c
    l' IntMap c
    r')
            | Bool
    otherwise  ->
                let (a
    a1,IntMap c
    r') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumRWithKey a -> Int -> b -> (a, c)
    f a
    a IntMap b
    r
                    (a
    a2,IntMap c
    l') = forall a b c.
    (a -> Int -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)
    mapAccumRWithKey a -> Int -> b -> (a, c)
    f a
    a1 IntMap b
    l
                in (a
    a2,forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap c
    l' IntMap c
    r')
          Tip Int
    k b
    x     -> let (a
    a',c
    x') = a -> Int -> b -> (a, c)
    f a
    a Int
    k b
    x in (a
    a',forall a. Int -> a -> IntMap a
    Tip Int
    k c
    x')
          IntMap b
    Nil         -> (a
    a,forall a. IntMap a
    Nil)

    -- | /O(n*min(n,W))/.
    -- @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.
    --
    -- The size of the result may be smaller if @f@ maps two or more distinct
    -- keys to the same new key.  In this case the value at the greatest of the
    -- original keys is retained.
    --
    -- > mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
    -- > mapKeys (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
    -- > mapKeys (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"

    mapKeys :: (Key->Key) -> IntMap a -> IntMap a
    mapKeys :: forall a. (Int -> Int) -> IntMap a -> IntMap a
    mapKeys Int -> Int
    f = forall a. [(Int, a)] -> IntMap a
    fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey (\Int
    k a
    x [(Int, a)]
    xs -> (Int -> Int
    f Int
    k, a
    x) forall a. a -> [a] -> [a]
    : [(Int, a)]
    xs) []

    -- | /O(n*min(n,W))/.
    -- @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.
    --
    -- The size of the result may be smaller if @f@ maps two or more distinct
    -- keys to the same new key.  In this case the associated values will be
    -- combined using @c@.
    --
    -- > mapKeysWith (++) (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
    -- > mapKeysWith (++) (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"

    mapKeysWith :: (a -> a -> a) -> (Key->Key) -> IntMap a -> IntMap a
    mapKeysWith :: forall a. (a -> a -> a) -> (Int -> Int) -> IntMap a -> IntMap a
    mapKeysWith a -> a -> a
    c Int -> Int
    f
      = forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
    fromListWith a -> a -> a
    c forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey (\Int
    k a
    x [(Int, a)]
    xs -> (Int -> Int
    f Int
    k, a
    x) forall a. a -> [a] -> [a]
    : [(Int, a)]
    xs) []

    -- | /O(n*min(n,W))/.
    -- @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@
    -- is strictly monotonic.
    -- That is, for any values @x@ and @y@, if @x@ < @y@ then @f x@ < @f y@.
    -- /The precondition is not checked./
    -- Semi-formally, we have:
    --
    -- > and [x < y ==> f x < f y | x <- ls, y <- ls]
    -- >                     ==> mapKeysMonotonic f s == mapKeys f s
    -- >     where ls = keys s
    --
    -- This means that @f@ maps distinct original keys to distinct resulting keys.
    -- This function has slightly better performance than 'mapKeys'.
    --
    -- > mapKeysMonotonic (\ k -> k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]

    mapKeysMonotonic :: (Key->Key) -> IntMap a -> IntMap a
    mapKeysMonotonic :: forall a. (Int -> Int) -> IntMap a -> IntMap a
    mapKeysMonotonic Int -> Int
    f
      = forall a. [(Int, a)] -> IntMap a
    fromDistinctAscList forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey (\Int
    k a
    x [(Int, a)]
    xs -> (Int -> Int
    f Int
    k, a
    x) forall a. a -> [a] -> [a]
    : [(Int, a)]
    xs) []

    {--------------------------------------------------------------------
      Filter
    --------------------------------------------------------------------}
    -- | /O(n)/. Filter all values that satisfy some predicate.
    --
    -- > filter (> "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
    -- > filter (> "x") (fromList [(5,"a"), (3,"b")]) == empty
    -- > filter (< "a") (fromList [(5,"a"), (3,"b")]) == empty

    filter :: (a -> Bool) -> IntMap a -> IntMap a
    filter :: forall a. (a -> Bool) -> IntMap a -> IntMap a
    filter a -> Bool
    p IntMap a
    m
      = forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
    filterWithKey (\Int
    _ a
    x -> a -> Bool
    p a
    x) IntMap a
    m

    -- | /O(n)/. Filter all keys\/values that satisfy some predicate.
    --
    -- > filterWithKey (\k _ -> k > 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"

    filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a
    filterWithKey :: forall a. (Int -> a -> Bool) -> IntMap a -> IntMap a
    filterWithKey Int -> a -> Bool
    predicate = IntMap a -> IntMap a
    go
        where
        go :: IntMap a -> IntMap a
    go IntMap a
    Nil           = forall a. IntMap a
    Nil
        go t :: IntMap a
    t@(Tip Int
    k a
    x)   = if Int -> a -> Bool
    predicate Int
    k a
    x then IntMap a
    t else forall a. IntMap a
    Nil
        go (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r) = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m (IntMap a -> IntMap a
    go IntMap a
    l) (IntMap a -> IntMap a
    go IntMap a
    r)

    -- | /O(n)/. Partition the map according to some predicate. The first
    -- map contains all elements that satisfy the predicate, the second all
    -- elements that fail the predicate. See also 'split'.
    --
    -- > partition (> "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
    -- > partition (< "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
    -- > partition (> "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])

    partition :: (a -> Bool) -> IntMap a -> (IntMap a,IntMap a)
    partition :: forall a. (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)
    partition a -> Bool
    p IntMap a
    m
      = forall a. (Int -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)
    partitionWithKey (\Int
    _ a
    x -> a -> Bool
    p a
    x) IntMap a
    m

    -- | /O(n)/. Partition the map according to some predicate. The first
    -- map contains all elements that satisfy the predicate, the second all
    -- elements that fail the predicate. See also 'split'.
    --
    -- > partitionWithKey (\ k _ -> k > 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
    -- > partitionWithKey (\ k _ -> k < 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
    -- > partitionWithKey (\ k _ -> k > 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])

    partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a,IntMap a)
    partitionWithKey :: forall a. (Int -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)
    partitionWithKey Int -> a -> Bool
    predicate0 IntMap a
    t0 = forall a b. StrictPair a b -> (a, b)
    toPair forall a b. (a -> b) -> a -> b
    $ forall {a}.
    (Int -> a -> Bool) -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int -> a -> Bool
    predicate0 IntMap a
    t0
      where
        go :: (Int -> a -> Bool) -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int -> a -> Bool
    predicate IntMap a
    t =
          case IntMap a
    t of
            Bin Int
    p Int
    m IntMap a
    l IntMap a
    r ->
              let (IntMap a
    l1 :*: IntMap a
    l2) = (Int -> a -> Bool) -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int -> a -> Bool
    predicate IntMap a
    l
                  (IntMap a
    r1 :*: IntMap a
    r2) = (Int -> a -> Bool) -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int -> a -> Bool
    predicate IntMap a
    r
              in forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m IntMap a
    l1 IntMap a
    r1 forall a b. a -> b -> StrictPair a b
    :*: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m IntMap a
    l2 IntMap a
    r2
            Tip Int
    k a
    x
              | Int -> a -> Bool
    predicate Int
    k a
    x -> (IntMap a
    t forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)
              | Bool
    otherwise     -> (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: IntMap a
    t)
            IntMap a
    Nil -> (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)

    -- | /O(n)/. Map values and collect the 'Just' results.
    --
    -- > let f x = if x == "a" then Just "new a" else Nothing
    -- > mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"

    mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybe :: forall a b. (a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybe a -> Maybe b
    f = forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey (\Int
    _ a
    x -> a -> Maybe b
    f a
    x)

    -- | /O(n)/. Map keys\/values and collect the 'Just' results.
    --
    -- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing
    -- > mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"

    mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey :: forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey Int -> a -> Maybe b
    f (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m (forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey Int -> a -> Maybe b
    f IntMap a
    l) (forall a b. (Int -> a -> Maybe b) -> IntMap a -> IntMap b
    mapMaybeWithKey Int -> a -> Maybe b
    f IntMap a
    r)
    mapMaybeWithKey Int -> a -> Maybe b
    f (Tip Int
    k a
    x) = case Int -> a -> Maybe b
    f Int
    k a
    x of
      Just b
    y  -> forall a. Int -> a -> IntMap a
    Tip Int
    k b
    y
      Maybe b
    Nothing -> forall a. IntMap a
    Nil
    mapMaybeWithKey Int -> a -> Maybe b
    _ IntMap a
    Nil = forall a. IntMap a
    Nil

    -- | /O(n)/. Map values and separate the 'Left' and 'Right' results.
    --
    -- > let f a = if a < "c" then Left a else Right a
    -- > mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
    -- >     == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
    -- >
    -- > mapEither (\ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
    -- >     == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])

    mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)
    mapEither :: forall a b c. (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)
    mapEither a -> Either b c
    f IntMap a
    m
      = forall a b c.
    (Int -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)
    mapEitherWithKey (\Int
    _ a
    x -> a -> Either b c
    f a
    x) IntMap a
    m

    -- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.
    --
    -- > let f k a = if k < 5 then Left (k * 2) else Right (a ++ a)
    -- > mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
    -- >     == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
    -- >
    -- > mapEitherWithKey (\_ a -> Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
    -- >     == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])

    mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)
    mapEitherWithKey :: forall a b c.
    (Int -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)
    mapEitherWithKey Int -> a -> Either b c
    f0 IntMap a
    t0 = forall a b. StrictPair a b -> (a, b)
    toPair forall a b. (a -> b) -> a -> b
    $ forall {t} {a} {a}.
    (Int -> t -> Either a a)
    -> IntMap t -> StrictPair (IntMap a) (IntMap a)
    go Int -> a -> Either b c
    f0 IntMap a
    t0
      where
        go :: (Int -> t -> Either a a)
    -> IntMap t -> StrictPair (IntMap a) (IntMap a)
    go Int -> t -> Either a a
    f (Bin Int
    p Int
    m IntMap t
    l IntMap t
    r) =
          forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m IntMap a
    l1 IntMap a
    r1 forall a b. a -> b -> StrictPair a b
    :*: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    p Int
    m IntMap a
    l2 IntMap a
    r2
          where
            (IntMap a
    l1 :*: IntMap a
    l2) = (Int -> t -> Either a a)
    -> IntMap t -> StrictPair (IntMap a) (IntMap a)
    go Int -> t -> Either a a
    f IntMap t
    l
            (IntMap a
    r1 :*: IntMap a
    r2) = (Int -> t -> Either a a)
    -> IntMap t -> StrictPair (IntMap a) (IntMap a)
    go Int -> t -> Either a a
    f IntMap t
    r
        go Int -> t -> Either a a
    f (Tip Int
    k t
    x) = case Int -> t -> Either a a
    f Int
    k t
    x of
          Left a
    y  -> (forall a. Int -> a -> IntMap a
    Tip Int
    k a
    y forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)
          Right a
    z -> (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: forall a. Int -> a -> IntMap a
    Tip Int
    k a
    z)
        go Int -> t -> Either a a
    _ IntMap t
    Nil = (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)

    -- | /O(min(n,W))/. The expression (@'split' k map@) is a pair @(map1,map2)@
    -- where all keys in @map1@ are lower than @k@ and all keys in
    -- @map2@ larger than @k@. Any key equal to @k@ is found in neither @map1@ nor @map2@.
    --
    -- > split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
    -- > split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
    -- > split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
    -- > split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
    -- > split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)

    split :: Key -> IntMap a -> (IntMap a, IntMap a)
    split :: forall a. Int -> IntMap a -> (IntMap a, IntMap a)
    split Int
    k IntMap a
    t =
      case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
            if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 -- handle negative numbers.
            then
              case forall {a}. Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k IntMap a
    l of
                (IntMap a
    lt :*: IntMap a
    gt) ->
                  let !lt' :: IntMap a
    lt' = forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    r IntMap a
    lt
                  in (IntMap a
    lt', IntMap a
    gt)
            else
              case forall {a}. Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k IntMap a
    r of
                (IntMap a
    lt :*: IntMap a
    gt) ->
                  let !gt' :: IntMap a
    gt' = forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    gt IntMap a
    l
                  in (IntMap a
    lt, IntMap a
    gt')
        IntMap a
    _ -> case forall {a}. Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k IntMap a
    t of
              (IntMap a
    lt :*: IntMap a
    gt) -> (IntMap a
    lt, IntMap a
    gt)
      where
        go :: Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k' t' :: IntMap a
    t'@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k' Int
    p Int
    m = if Int
    k' forall a. Ord a => a -> a -> Bool
    > Int
    p then IntMap a
    t' forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil else forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: IntMap a
    t'
          | Int -> Int -> Bool
    zero Int
    k' Int
    m = case Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k' IntMap a
    l of (IntMap a
    lt :*: IntMap a
    gt) -> IntMap a
    lt forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    gt IntMap a
    r
          | Bool
    otherwise = case Int -> IntMap a -> StrictPair (IntMap a) (IntMap a)
    go Int
    k' IntMap a
    r of (IntMap a
    lt :*: IntMap a
    gt) -> forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    l IntMap a
    lt forall a b. a -> b -> StrictPair a b
    :*: IntMap a
    gt
        go Int
    k' t' :: IntMap a
    t'@(Tip Int
    ky a
    _)
          | Int
    k' forall a. Ord a => a -> a -> Bool
    > Int
    ky   = (IntMap a
    t' forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)
          | Int
    k' forall a. Ord a => a -> a -> Bool
    < Int
    ky   = (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: IntMap a
    t')
          | Bool
    otherwise = (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)
        go Int
    _ IntMap a
    Nil = (forall a. IntMap a
    Nil forall a b. a -> b -> StrictPair a b
    :*: forall a. IntMap a
    Nil)

    data SplitLookup a = SplitLookup !(IntMap a) !(Maybe a) !(IntMap a)

    mapLT :: (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapLT :: forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapLT IntMap a -> IntMap a
    f (SplitLookup IntMap a
    lt Maybe a
    fnd IntMap a
    gt) = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup (IntMap a -> IntMap a
    f IntMap a
    lt) Maybe a
    fnd IntMap a
    gt
    {-# INLINE mapLT #-}

    mapGT :: (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapGT :: forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapGT IntMap a -> IntMap a
    f (SplitLookup IntMap a
    lt Maybe a
    fnd IntMap a
    gt) = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup IntMap a
    lt Maybe a
    fnd (IntMap a -> IntMap a
    f IntMap a
    gt)
    {-# INLINE mapGT #-}

    -- | /O(min(n,W))/. Performs a 'split' but also returns whether the pivot
    -- key was found in the original map.
    --
    -- > splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
    -- > splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
    -- > splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
    -- > splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
    -- > splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)

    splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)
    splitLookup :: forall a. Int -> IntMap a -> (IntMap a, Maybe a, IntMap a)
    splitLookup Int
    k IntMap a
    t =
      case
        case IntMap a
    t of
          Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
            | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 ->
              if Int
    k forall a. Ord a => a -> a -> Bool
    >= Int
    0 -- handle negative numbers.
              then forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapLT (forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    r) (forall {a}. Int -> IntMap a -> SplitLookup a
    go Int
    k IntMap a
    l)
              else forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapGT (forall a. IntMap a -> IntMap a -> IntMap a
    `union` IntMap a
    l) (forall {a}. Int -> IntMap a -> SplitLookup a
    go Int
    k IntMap a
    r)
          IntMap a
    _ -> forall {a}. Int -> IntMap a -> SplitLookup a
    go Int
    k IntMap a
    t
      of SplitLookup IntMap a
    lt Maybe a
    fnd IntMap a
    gt -> (IntMap a
    lt, Maybe a
    fnd, IntMap a
    gt)
      where
        go :: Int -> IntMap a -> SplitLookup a
    go Int
    k' t' :: IntMap a
    t'@(Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
          | Int -> Int -> Int -> Bool
    nomatch Int
    k' Int
    p Int
    m =
              if Int
    k' forall a. Ord a => a -> a -> Bool
    > Int
    p
              then forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup IntMap a
    t' forall a. Maybe a
    Nothing forall a. IntMap a
    Nil
              else forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup forall a. IntMap a
    Nil forall a. Maybe a
    Nothing IntMap a
    t'
          | Int -> Int -> Bool
    zero Int
    k' Int
    m = forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapGT (forall a. IntMap a -> IntMap a -> IntMap a
    `union` IntMap a
    r) (Int -> IntMap a -> SplitLookup a
    go Int
    k' IntMap a
    l)
          | Bool
    otherwise = forall a. (IntMap a -> IntMap a) -> SplitLookup a -> SplitLookup a
    mapLT (forall a. IntMap a -> IntMap a -> IntMap a
    union IntMap a
    l) (Int -> IntMap a -> SplitLookup a
    go Int
    k' IntMap a
    r)
        go Int
    k' t' :: IntMap a
    t'@(Tip Int
    ky a
    y)
          | Int
    k' forall a. Ord a => a -> a -> Bool
    > Int
    ky   = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup IntMap a
    t'  forall a. Maybe a
    Nothing  forall a. IntMap a
    Nil
          | Int
    k' forall a. Ord a => a -> a -> Bool
    < Int
    ky   = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup forall a. IntMap a
    Nil forall a. Maybe a
    Nothing  IntMap a
    t'
          | Bool
    otherwise = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup forall a. IntMap a
    Nil (forall a. a -> Maybe a
    Just a
    y) forall a. IntMap a
    Nil
        go Int
    _ IntMap a
    Nil      = forall a. IntMap a -> Maybe a -> IntMap a -> SplitLookup a
    SplitLookup forall a. IntMap a
    Nil forall a. Maybe a
    Nothing  forall a. IntMap a
    Nil

    {--------------------------------------------------------------------
      Fold
    --------------------------------------------------------------------}
    -- | /O(n)/. Fold the values in the map using the given right-associative
    -- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.
    --
    -- For example,
    --
    -- > elems map = foldr (:) [] map
    --
    -- > let f a len = len + (length a)
    -- > foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
    foldr :: (a -> b -> b) -> b -> IntMap a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr a -> b -> b
    f b
    z = \IntMap a
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    l) IntMap a
    r -- put negative numbers before
          | Bool
    otherwise -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    r) IntMap a
    l
        IntMap a
    _ -> b -> IntMap a -> b
    go b
    z IntMap a
    t
      where
        go :: b -> IntMap a -> b
    go b
    z' IntMap a
    Nil           = b
    z'
        go b
    z' (Tip Int
    _ a
    x)     = a -> b -> b
    f a
    x b
    z'
        go b
    z' (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z' IntMap a
    r) IntMap a
    l
    {-# INLINE foldr #-}

    -- | /O(n)/. A strict version of 'foldr'. Each application of the operator is
    -- evaluated before using the result in the next application. This
    -- function is strict in the starting value.
    foldr' :: (a -> b -> b) -> b -> IntMap a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr' a -> b -> b
    f b
    z = \IntMap a
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    l) IntMap a
    r -- put negative numbers before
          | Bool
    otherwise -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    r) IntMap a
    l
        IntMap a
    _ -> b -> IntMap a -> b
    go b
    z IntMap a
    t
      where
        go :: b -> IntMap a -> b
    go !b
    z' IntMap a
    Nil          = b
    z'
        go b
    z' (Tip Int
    _ a
    x)     = a -> b -> b
    f a
    x b
    z'
        go b
    z' (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z' IntMap a
    r) IntMap a
    l
    {-# INLINE foldr' #-}

    -- | /O(n)/. Fold the values in the map using the given left-associative
    -- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.
    --
    -- For example,
    --
    -- > elems = reverse . foldl (flip (:)) []
    --
    -- > let f len a = len + (length a)
    -- > foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
    foldl :: (a -> b -> a) -> a -> IntMap b -> a
    foldl :: forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl a -> b -> a
    f a
    z = \IntMap b
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap b
    t of
        Bin Int
    _ Int
    m IntMap b
    l IntMap b
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    r) IntMap b
    l -- put negative numbers before
          | Bool
    otherwise -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    l) IntMap b
    r
        IntMap b
    _ -> a -> IntMap b -> a
    go a
    z IntMap b
    t
      where
        go :: a -> IntMap b -> a
    go a
    z' IntMap b
    Nil           = a
    z'
        go a
    z' (Tip Int
    _ b
    x)     = a -> b -> a
    f a
    z' b
    x
        go a
    z' (Bin Int
    _ Int
    _ IntMap b
    l IntMap b
    r) = a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z' IntMap b
    l) IntMap b
    r
    {-# INLINE foldl #-}

    -- | /O(n)/. A strict version of 'foldl'. Each application of the operator is
    -- evaluated before using the result in the next application. This
    -- function is strict in the starting value.
    foldl' :: (a -> b -> a) -> a -> IntMap b -> a
    foldl' :: forall b a. (b -> a -> b) -> b -> IntMap a -> b
    foldl' a -> b -> a
    f a
    z = \IntMap b
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap b
    t of
        Bin Int
    _ Int
    m IntMap b
    l IntMap b
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    r) IntMap b
    l -- put negative numbers before
          | Bool
    otherwise -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    l) IntMap b
    r
        IntMap b
    _ -> a -> IntMap b -> a
    go a
    z IntMap b
    t
      where
        go :: a -> IntMap b -> a
    go !a
    z' IntMap b
    Nil          = a
    z'
        go a
    z' (Tip Int
    _ b
    x)     = a -> b -> a
    f a
    z' b
    x
        go a
    z' (Bin Int
    _ Int
    _ IntMap b
    l IntMap b
    r) = a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z' IntMap b
    l) IntMap b
    r
    {-# INLINE foldl' #-}

    -- | /O(n)/. Fold the keys and values in the map using the given right-associative
    -- binary operator, such that
    -- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.
    --
    -- For example,
    --
    -- > keys map = foldrWithKey (\k x ks -> k:ks) [] map
    --
    -- > let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
    -- > foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
    foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey :: forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey Int -> a -> b -> b
    f b
    z = \IntMap a
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    l) IntMap a
    r -- put negative numbers before
          | Bool
    otherwise -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    r) IntMap a
    l
        IntMap a
    _ -> b -> IntMap a -> b
    go b
    z IntMap a
    t
      where
        go :: b -> IntMap a -> b
    go b
    z' IntMap a
    Nil           = b
    z'
        go b
    z' (Tip Int
    kx a
    x)    = Int -> a -> b -> b
    f Int
    kx a
    x b
    z'
        go b
    z' (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z' IntMap a
    r) IntMap a
    l
    {-# INLINE foldrWithKey #-}

    -- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is
    -- evaluated before using the result in the next application. This
    -- function is strict in the starting value.
    foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey' :: forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey' Int -> a -> b -> b
    f b
    z = \IntMap a
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap a
    t of
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    l) IntMap a
    r -- put negative numbers before
          | Bool
    otherwise -> b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z IntMap a
    r) IntMap a
    l
        IntMap a
    _ -> b -> IntMap a -> b
    go b
    z IntMap a
    t
      where
        go :: b -> IntMap a -> b
    go !b
    z' IntMap a
    Nil          = b
    z'
        go b
    z' (Tip Int
    kx a
    x)    = Int -> a -> b -> b
    f Int
    kx a
    x b
    z'
        go b
    z' (Bin Int
    _ Int
    _ IntMap a
    l IntMap a
    r) = b -> IntMap a -> b
    go (b -> IntMap a -> b
    go b
    z' IntMap a
    r) IntMap a
    l
    {-# INLINE foldrWithKey' #-}

    -- | /O(n)/. Fold the keys and values in the map using the given left-associative
    -- binary operator, such that
    -- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.
    --
    -- For example,
    --
    -- > keys = reverse . foldlWithKey (\ks k x -> k:ks) []
    --
    -- > let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
    -- > foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
    foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a
    foldlWithKey :: forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
    foldlWithKey a -> Int -> b -> a
    f a
    z = \IntMap b
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap b
    t of
        Bin Int
    _ Int
    m IntMap b
    l IntMap b
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    r) IntMap b
    l -- put negative numbers before
          | Bool
    otherwise -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    l) IntMap b
    r
        IntMap b
    _ -> a -> IntMap b -> a
    go a
    z IntMap b
    t
      where
        go :: a -> IntMap b -> a
    go a
    z' IntMap b
    Nil           = a
    z'
        go a
    z' (Tip Int
    kx b
    x)    = a -> Int -> b -> a
    f a
    z' Int
    kx b
    x
        go a
    z' (Bin Int
    _ Int
    _ IntMap b
    l IntMap b
    r) = a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z' IntMap b
    l) IntMap b
    r
    {-# INLINE foldlWithKey #-}

    -- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is
    -- evaluated before using the result in the next application. This
    -- function is strict in the starting value.
    foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a
    foldlWithKey' :: forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
    foldlWithKey' a -> Int -> b -> a
    f a
    z = \IntMap b
    t ->      -- Use lambda t to be inlinable with two arguments only.
      case IntMap b
    t of
        Bin Int
    _ Int
    m IntMap b
    l IntMap b
    r
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    r) IntMap b
    l -- put negative numbers before
          | Bool
    otherwise -> a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z IntMap b
    l) IntMap b
    r
        IntMap b
    _ -> a -> IntMap b -> a
    go a
    z IntMap b
    t
      where
        go :: a -> IntMap b -> a
    go !a
    z' IntMap b
    Nil          = a
    z'
        go a
    z' (Tip Int
    kx b
    x)    = a -> Int -> b -> a
    f a
    z' Int
    kx b
    x
        go a
    z' (Bin Int
    _ Int
    _ IntMap b
    l IntMap b
    r) = a -> IntMap b -> a
    go (a -> IntMap b -> a
    go a
    z' IntMap b
    l) IntMap b
    r
    {-# INLINE foldlWithKey' #-}

    -- | /O(n)/. Fold the keys and values in the map using the given monoid, such that
    --
    -- @'foldMapWithKey' f = 'Prelude.fold' . 'mapWithKey' f@
    --
    -- This can be an asymptotically faster than 'foldrWithKey' or 'foldlWithKey' for some monoids.
    --
    -- @since 0.5.4
    foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m
    foldMapWithKey :: forall m a. Monoid m => (Int -> a -> m) -> IntMap a -> m
    foldMapWithKey Int -> a -> m
    f = IntMap a -> m
    go
      where
        go :: IntMap a -> m
    go IntMap a
    Nil           = forall a. Monoid a => a
    mempty
        go (Tip Int
    kx a
    x)    = Int -> a -> m
    f Int
    kx a
    x
        go (Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r)
          | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0     = IntMap a -> m
    go IntMap a
    r forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> m
    go IntMap a
    l
          | Bool
    otherwise = IntMap a -> m
    go IntMap a
    l forall a. Monoid a => a -> a -> a
    `mappend` IntMap a -> m
    go IntMap a
    r
    {-# INLINE foldMapWithKey #-}

    {--------------------------------------------------------------------
      List variations
    --------------------------------------------------------------------}
    -- | /O(n)/.
    -- Return all elements of the map in the ascending order of their keys.
    -- Subject to list fusion.
    --
    -- > elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
    -- > elems empty == []

    elems :: IntMap a -> [a]
    elems :: forall a. IntMap a -> [a]
    elems = forall a b. (a -> b -> b) -> b -> IntMap a -> b
    foldr (:) []

    -- | /O(n)/. Return all keys of the map in ascending order. Subject to list
    -- fusion.
    --
    -- > keys (fromList [(5,"a"), (3,"b")]) == [3,5]
    -- > keys empty == []

    keys  :: IntMap a -> [Key]
    keys :: forall a. IntMap a -> [Int]
    keys = forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey (\Int
    k a
    _ [Int]
    ks -> Int
    k forall a. a -> [a] -> [a]
    : [Int]
    ks) []

    -- | /O(n)/. An alias for 'toAscList'. Returns all key\/value pairs in the
    -- map in ascending key order. Subject to list fusion.
    --
    -- > assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
    -- > assocs empty == []

    assocs :: IntMap a -> [(Key,a)]
    assocs :: forall a. IntMap a -> [(Int, a)]
    assocs = forall a. IntMap a -> [(Int, a)]
    toAscList

    -- | /O(n*min(n,W))/. The set of all keys of the map.
    --
    -- > keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
    -- > keysSet empty == Data.IntSet.empty

    keysSet :: IntMap a -> IntSet.IntSet
    keysSet :: forall a. IntMap a -> IntSet
    keysSet IntMap a
    Nil = IntSet
    IntSet.Nil
    keysSet (Tip Int
    kx a
    _) = Int -> IntSet
    IntSet.singleton Int
    kx
    keysSet (Bin Int
    p Int
    m IntMap a
    l IntMap a
    r)
      | Int
    m forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.suffixBitMask forall a. Eq a => a -> a -> Bool
    == Int
    0 = Int -> Int -> IntSet -> IntSet -> IntSet
    IntSet.Bin Int
    p Int
    m (forall a. IntMap a -> IntSet
    keysSet IntMap a
    l) (forall a. IntMap a -> IntSet
    keysSet IntMap a
    r)
      | Bool
    otherwise = Int -> Nat -> IntSet
    IntSet.Tip (Int
    p forall a. Bits a => a -> a -> a
    .&. Int
    IntSet.prefixBitMask) (forall {a}. Nat -> IntMap a -> Nat
    computeBm (forall {a}. Nat -> IntMap a -> Nat
    computeBm Nat
    0 IntMap a
    l) IntMap a
    r)
      where computeBm :: Nat -> IntMap a -> Nat
    computeBm !Nat
    acc (Bin Int
    _ Int
    _ IntMap a
    l' IntMap a
    r') = Nat -> IntMap a -> Nat
    computeBm (Nat -> IntMap a -> Nat
    computeBm Nat
    acc IntMap a
    l') IntMap a
    r'
            computeBm Nat
    acc (Tip Int
    kx a
    _) = Nat
    acc forall a. Bits a => a -> a -> a
    .|. Int -> Nat
    IntSet.bitmapOf Int
    kx
            computeBm Nat
    _   IntMap a
    Nil = forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.IntSet.keysSet: Nil"

    -- | /O(n)/. Build a map from a set of keys and a function which for each key
    -- computes its value.
    --
    -- > fromSet (\k -> replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
    -- > fromSet undefined Data.IntSet.empty == empty

    fromSet :: (Key -> a) -> IntSet.IntSet -> IntMap a
    fromSet :: forall a. (Int -> a) -> IntSet -> IntMap a
    fromSet Int -> a
    _ IntSet
    IntSet.Nil = forall a. IntMap a
    Nil
    fromSet Int -> a
    f (IntSet.Bin Int
    p Int
    m IntSet
    l IntSet
    r) = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (forall a. (Int -> a) -> IntSet -> IntMap a
    fromSet Int -> a
    f IntSet
    l) (forall a. (Int -> a) -> IntSet -> IntMap a
    fromSet Int -> a
    f IntSet
    r)
    fromSet Int -> a
    f (IntSet.Tip Int
    kx Nat
    bm) = forall {a}. (Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    f Int
    kx Nat
    bm (Int
    IntSet.suffixBitMask forall a. Num a => a -> a -> a
    + Int
    1)
      where
        -- This is slightly complicated, as we to convert the dense
        -- representation of IntSet into tree representation of IntMap.
        --
        -- We are given a nonzero bit mask 'bmask' of 'bits' bits with
        -- prefix 'prefix'. We split bmask into halves corresponding
        -- to left and right subtree. If they are both nonempty, we
        -- create a Bin node, otherwise exactly one of them is nonempty
        -- and we construct the IntMap from that half.
        buildTree :: (Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    g !Int
    prefix !Nat
    bmask Int
    bits = case Int
    bits of
          Int
    0 -> forall a. Int -> a -> IntMap a
    Tip Int
    prefix (Int -> a
    g Int
    prefix)
          Int
    _ -> case Nat -> Int
    intFromNat ((Int -> Nat
    natFromInt Int
    bits) Nat -> Int -> Nat
    `shiftRL` Int
    1) of
            Int
    bits2
              | Nat
    bmask forall a. Bits a => a -> a -> a
    .&. ((Nat
    1 Nat -> Int -> Nat
    `shiftLL` Int
    bits2) forall a. Num a => a -> a -> a
    - Nat
    1) forall a. Eq a => a -> a -> Bool
    == Nat
    0 ->
                  (Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    g (Int
    prefix forall a. Num a => a -> a -> a
    + Int
    bits2) (Nat
    bmask Nat -> Int -> Nat
    `shiftRL` Int
    bits2) Int
    bits2
              | (Nat
    bmask Nat -> Int -> Nat
    `shiftRL` Int
    bits2) forall a. Bits a => a -> a -> a
    .&. ((Nat
    1 Nat -> Int -> Nat
    `shiftLL` Int
    bits2) forall a. Num a => a -> a -> a
    - Nat
    1) forall a. Eq a => a -> a -> Bool
    == Nat
    0 ->
                  (Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    g Int
    prefix Nat
    bmask Int
    bits2
              | Bool
    otherwise ->
                  forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    prefix Int
    bits2
                    ((Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    g Int
    prefix Nat
    bmask Int
    bits2)
                    ((Int -> a) -> Int -> Nat -> Int -> IntMap a
    buildTree Int -> a
    g (Int
    prefix forall a. Num a => a -> a -> a
    + Int
    bits2) (Nat
    bmask Nat -> Int -> Nat
    `shiftRL` Int
    bits2) Int
    bits2)

    {--------------------------------------------------------------------
      Lists
    --------------------------------------------------------------------}
    #if __GLASGOW_HASKELL__ >= 708
    -- | @since 0.5.6.2
    instance GHCExts.IsList (IntMap a) where
      type Item (IntMap a) = (Key,a)
      fromList :: [Item (IntMap a)] -> IntMap a
    fromList = forall a. [(Int, a)] -> IntMap a
    fromList
      toList :: IntMap a -> [Item (IntMap a)]
    toList   = forall a. IntMap a -> [(Int, a)]
    toList
    #endif

    -- | /O(n)/. Convert the map to a list of key\/value pairs. Subject to list
    -- fusion.
    --
    -- > toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
    -- > toList empty == []

    toList :: IntMap a -> [(Key,a)]
    toList :: forall a. IntMap a -> [(Int, a)]
    toList = forall a. IntMap a -> [(Int, a)]
    toAscList

    -- | /O(n)/. Convert the map to a list of key\/value pairs where the
    -- keys are in ascending order. Subject to list fusion.
    --
    -- > toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]

    toAscList :: IntMap a -> [(Key,a)]
    toAscList :: forall a. IntMap a -> [(Int, a)]
    toAscList = forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey (\Int
    k a
    x [(Int, a)]
    xs -> (Int
    k,a
    x)forall a. a -> [a] -> [a]
    :[(Int, a)]
    xs) []

    -- | /O(n)/. Convert the map to a list of key\/value pairs where the keys
    -- are in descending order. Subject to list fusion.
    --
    -- > toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]

    toDescList :: IntMap a -> [(Key,a)]
    toDescList :: forall a. IntMap a -> [(Int, a)]
    toDescList = forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
    foldlWithKey (\[(Int, a)]
    xs Int
    k a
    x -> (Int
    k,a
    x)forall a. a -> [a] -> [a]
    :[(Int, a)]
    xs) []

    -- List fusion for the list generating functions.
    #if __GLASGOW_HASKELL__
    -- The foldrFB and foldlFB are fold{r,l}WithKey equivalents, used for list fusion.
    -- They are important to convert unfused methods back, see mapFB in prelude.
    foldrFB :: (Key -> a -> b -> b) -> b -> IntMap a -> b
    foldrFB :: forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrFB = forall a b. (Int -> a -> b -> b) -> b -> IntMap a -> b
    foldrWithKey
    {-# INLINE[0] foldrFB #-}
    foldlFB :: (a -> Key -> b -> a) -> a -> IntMap b -> a
    foldlFB :: forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
    foldlFB = forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
    foldlWithKey
    {-# INLINE[0] foldlFB #-}

    -- Inline assocs and toList, so that we need to fuse only toAscList.
    {-# INLINE assocs #-}
    {-# INLINE toList #-}

    -- The fusion is enabled up to phase 2 included. If it does not succeed,
    -- convert in phase 1 the expanded elems,keys,to{Asc,Desc}List calls back to
    -- elems,keys,to{Asc,Desc}List.  In phase 0, we inline fold{lr}FB (which were
    -- used in a list fusion, otherwise it would go away in phase 1), and let compiler
    -- do whatever it wants with elems,keys,to{Asc,Desc}List -- it was forbidden to
    -- inline it before phase 0, otherwise the fusion rules would not fire at all.
    {-# NOINLINE[0] elems #-}
    {-# NOINLINE[0] keys #-}
    {-# NOINLINE[0] toAscList #-}
    {-# NOINLINE[0] toDescList #-}
    {-# RULES "IntMap.elems" [~1] forall m . elems m = build (\c n -> foldrFB (\_ x xs -> c x xs) n m) #-}
    {-# RULES "IntMap.elemsBack" [1] foldrFB (\_ x xs -> x : xs) [] = elems #-}
    {-# RULES "IntMap.keys" [~1] forall m . keys m = build (\c n -> foldrFB (\k _ xs -> c k xs) n m) #-}
    {-# RULES "IntMap.keysBack" [1] foldrFB (\k _ xs -> k : xs) [] = keys #-}
    {-# RULES "IntMap.toAscList" [~1] forall m . toAscList m = build (\c n -> foldrFB (\k x xs -> c (k,x) xs) n m) #-}
    {-# RULES "IntMap.toAscListBack" [1] foldrFB (\k x xs -> (k, x) : xs) [] = toAscList #-}
    {-# RULES "IntMap.toDescList" [~1] forall m . toDescList m = build (\c n -> foldlFB (\xs k x -> c (k,x) xs) n m) #-}
    {-# RULES "IntMap.toDescListBack" [1] foldlFB (\xs k x -> (k, x) : xs) [] = toDescList #-}
    #endif

    -- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs.
    --
    -- > fromList [] == empty
    -- > fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
    -- > fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]

    fromList :: [(Key,a)] -> IntMap a
    fromList :: forall a. [(Int, a)] -> IntMap a
    fromList [(Int, a)]
    xs
      = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' forall {a}. IntMap a -> (Int, a) -> IntMap a
    ins forall a. IntMap a
    empty [(Int, a)]
    xs
      where
        ins :: IntMap a -> (Int, a) -> IntMap a
    ins IntMap a
    t (Int
    k,a
    x)  = forall a. Int -> a -> IntMap a -> IntMap a
    insert Int
    k a
    x IntMap a
    t

    -- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.
    --
    -- > fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "ab"), (5, "cba")]
    -- > fromListWith (++) [] == empty

    fromListWith :: (a -> a -> a) -> [(Key,a)] -> IntMap a
    fromListWith :: forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
    fromListWith a -> a -> a
    f [(Int, a)]
    xs
      = forall a. (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromListWithKey (\Int
    _ a
    x a
    y -> a -> a -> a
    f a
    x a
    y) [(Int, a)]
    xs

    -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs with a combining function. See also fromAscListWithKey'.
    --
    -- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
    -- > fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
    -- > fromListWithKey f [] == empty

    fromListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a
    fromListWithKey :: forall a. (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromListWithKey Int -> a -> a -> a
    f [(Int, a)]
    xs
      = forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' IntMap a -> (Int, a) -> IntMap a
    ins forall a. IntMap a
    empty [(Int, a)]
    xs
      where
        ins :: IntMap a -> (Int, a) -> IntMap a
    ins IntMap a
    t (Int
    k,a
    x) = forall a. (Int -> a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
    insertWithKey Int -> a -> a -> a
    f Int
    k a
    x IntMap a
    t

    -- | /O(n)/. Build a map from a list of key\/value pairs where
    -- the keys are in ascending order.
    --
    -- > fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
    -- > fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]

    fromAscList :: [(Key,a)] -> IntMap a
    fromAscList :: forall a. [(Int, a)] -> IntMap a
    fromAscList = forall a.
    Distinct -> (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromMonoListWithKey Distinct
    Nondistinct (\Int
    _ a
    x a
    _ -> a
    x)
    {-# NOINLINE fromAscList #-}

    -- | /O(n)/. Build a map from a list of key\/value pairs where
    -- the keys are in ascending order, with a combining function on equal keys.
    -- /The precondition (input list is ascending) is not checked./
    --
    -- > fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]

    fromAscListWith :: (a -> a -> a) -> [(Key,a)] -> IntMap a
    fromAscListWith :: forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
    fromAscListWith a -> a -> a
    f = forall a.
    Distinct -> (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromMonoListWithKey Distinct
    Nondistinct (\Int
    _ a
    x a
    y -> a -> a -> a
    f a
    x a
    y)
    {-# NOINLINE fromAscListWith #-}

    -- | /O(n)/. Build a map from a list of key\/value pairs where
    -- the keys are in ascending order, with a combining function on equal keys.
    -- /The precondition (input list is ascending) is not checked./
    --
    -- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
    -- > fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]

    fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a
    fromAscListWithKey :: forall a. (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromAscListWithKey Int -> a -> a -> a
    f = forall a.
    Distinct -> (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromMonoListWithKey Distinct
    Nondistinct Int -> a -> a -> a
    f
    {-# NOINLINE fromAscListWithKey #-}

    -- | /O(n)/. Build a map from a list of key\/value pairs where
    -- the keys are in ascending order and all distinct.
    -- /The precondition (input list is strictly ascending) is not checked./
    --
    -- > fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]

    fromDistinctAscList :: [(Key,a)] -> IntMap a
    fromDistinctAscList :: forall a. [(Int, a)] -> IntMap a
    fromDistinctAscList = forall a.
    Distinct -> (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromMonoListWithKey Distinct
    Distinct (\Int
    _ a
    x a
    _ -> a
    x)
    {-# NOINLINE fromDistinctAscList #-}

    -- | /O(n)/. Build a map from a list of key\/value pairs with monotonic keys
    -- and a combining function.
    --
    -- The precise conditions under which this function works are subtle:
    -- For any branch mask, keys with the same prefix w.r.t. the branch
    -- mask must occur consecutively in the list.

    fromMonoListWithKey :: Distinct -> (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a
    fromMonoListWithKey :: forall a.
    Distinct -> (Int -> a -> a -> a) -> [(Int, a)] -> IntMap a
    fromMonoListWithKey Distinct
    distinct Int -> a -> a -> a
    f = [(Int, a)] -> IntMap a
    go
      where
        go :: [(Int, a)] -> IntMap a
    go []              = forall a. IntMap a
    Nil
        go ((Int
    kx,a
    vx) : [(Int, a)]
    zs1) = Int -> a -> [(Int, a)] -> IntMap a
    addAll' Int
    kx a
    vx [(Int, a)]
    zs1

        -- `addAll'` collects all keys equal to `kx` into a single value,
        -- and then proceeds with `addAll`.
        addAll' :: Int -> a -> [(Int, a)] -> IntMap a
    addAll' !Int
    kx a
    vx []
            = forall a. Int -> a -> IntMap a
    Tip Int
    kx a
    vx
        addAll' !Int
    kx a
    vx ((Int
    ky,a
    vy) : [(Int, a)]
    zs)
            | Distinct
    Nondistinct <- Distinct
    distinct, Int
    kx forall a. Eq a => a -> a -> Bool
    == Int
    ky
            = let v :: a
    v = Int -> a -> a -> a
    f Int
    kx a
    vy a
    vx in Int -> a -> [(Int, a)] -> IntMap a
    addAll' Int
    ky a
    v [(Int, a)]
    zs
            -- inlined: | otherwise = addAll kx (Tip kx vx) (ky : zs)
            | Int
    m <- Int -> Int -> Int
    branchMask Int
    kx Int
    ky
            , Inserted IntMap a
    ty [(Int, a)]
    zs' <- Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' Int
    m Int
    ky a
    vy [(Int, a)]
    zs
            = Int -> IntMap a -> [(Int, a)] -> IntMap a
    addAll Int
    kx (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask Int
    m Int
    ky IntMap a
    ty {-kx-} (forall a. Int -> a -> IntMap a
    Tip Int
    kx a
    vx)) [(Int, a)]
    zs'

        -- for `addAll` and `addMany`, kx is /a/ key inside the tree `tx`
        -- `addAll` consumes the rest of the list, adding to the tree `tx`
        addAll :: Int -> IntMap a -> [(Int, a)] -> IntMap a
    addAll !Int
    _kx !IntMap a
    tx []
            = IntMap a
    tx
        addAll !Int
    kx !IntMap a
    tx ((Int
    ky,a
    vy) : [(Int, a)]
    zs)
            | Int
    m <- Int -> Int -> Int
    branchMask Int
    kx Int
    ky
            , Inserted IntMap a
    ty [(Int, a)]
    zs' <- Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' Int
    m Int
    ky a
    vy [(Int, a)]
    zs
            = Int -> IntMap a -> [(Int, a)] -> IntMap a
    addAll Int
    kx (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask Int
    m Int
    ky IntMap a
    ty {-kx-} IntMap a
    tx) [(Int, a)]
    zs'

        -- `addMany'` is similar to `addAll'`, but proceeds with `addMany'`.
        addMany' :: Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' !Int
    _m !Int
    kx a
    vx []
            = forall a. IntMap a -> [(Int, a)] -> Inserted a
    Inserted (forall a. Int -> a -> IntMap a
    Tip Int
    kx a
    vx) []
        addMany' !Int
    m !Int
    kx a
    vx zs0 :: [(Int, a)]
    zs0@((Int
    ky,a
    vy) : [(Int, a)]
    zs)
            | Distinct
    Nondistinct <- Distinct
    distinct, Int
    kx forall a. Eq a => a -> a -> Bool
    == Int
    ky
            = let v :: a
    v = Int -> a -> a -> a
    f Int
    kx a
    vy a
    vx in Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' Int
    m Int
    ky a
    v [(Int, a)]
    zs
            -- inlined: | otherwise = addMany m kx (Tip kx vx) (ky : zs)
            | Int -> Int -> Int
    mask Int
    kx Int
    m forall a. Eq a => a -> a -> Bool
    /= Int -> Int -> Int
    mask Int
    ky Int
    m
            = forall a. IntMap a -> [(Int, a)] -> Inserted a
    Inserted (forall a. Int -> a -> IntMap a
    Tip Int
    kx a
    vx) [(Int, a)]
    zs0
            | Int
    mxy <- Int -> Int -> Int
    branchMask Int
    kx Int
    ky
            , Inserted IntMap a
    ty [(Int, a)]
    zs' <- Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' Int
    mxy Int
    ky a
    vy [(Int, a)]
    zs
            = Int -> Int -> IntMap a -> [(Int, a)] -> Inserted a
    addMany Int
    m Int
    kx (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask Int
    mxy Int
    ky IntMap a
    ty {-kx-} (forall a. Int -> a -> IntMap a
    Tip Int
    kx a
    vx)) [(Int, a)]
    zs'

        -- `addAll` adds to `tx` all keys whose prefix w.r.t. `m` agrees with `kx`.
        addMany :: Int -> Int -> IntMap a -> [(Int, a)] -> Inserted a
    addMany !Int
    _m !Int
    _kx IntMap a
    tx []
            = forall a. IntMap a -> [(Int, a)] -> Inserted a
    Inserted IntMap a
    tx []
        addMany !Int
    m !Int
    kx IntMap a
    tx zs0 :: [(Int, a)]
    zs0@((Int
    ky,a
    vy) : [(Int, a)]
    zs)
            | Int -> Int -> Int
    mask Int
    kx Int
    m forall a. Eq a => a -> a -> Bool
    /= Int -> Int -> Int
    mask Int
    ky Int
    m
            = forall a. IntMap a -> [(Int, a)] -> Inserted a
    Inserted IntMap a
    tx [(Int, a)]
    zs0
            | Int
    mxy <- Int -> Int -> Int
    branchMask Int
    kx Int
    ky
            , Inserted IntMap a
    ty [(Int, a)]
    zs' <- Int -> Int -> a -> [(Int, a)] -> Inserted a
    addMany' Int
    mxy Int
    ky a
    vy [(Int, a)]
    zs
            = Int -> Int -> IntMap a -> [(Int, a)] -> Inserted a
    addMany Int
    m Int
    kx (forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask Int
    mxy Int
    ky IntMap a
    ty {-kx-} IntMap a
    tx) [(Int, a)]
    zs'
    {-# INLINE fromMonoListWithKey #-}

    data Inserted a = Inserted !(IntMap a) ![(Key,a)]

    data Distinct = Distinct | Nondistinct

    {--------------------------------------------------------------------
      Eq
    --------------------------------------------------------------------}
    instance Eq a => Eq (IntMap a) where
      IntMap a
    t1 == :: IntMap a -> IntMap a -> Bool
    == IntMap a
    t2  = forall a. Eq a => IntMap a -> IntMap a -> Bool
    equal IntMap a
    t1 IntMap a
    t2
      IntMap a
    t1 /= :: IntMap a -> IntMap a -> Bool
    /= IntMap a
    t2  = forall a. Eq a => IntMap a -> IntMap a -> Bool
    nequal IntMap a
    t1 IntMap a
    t2

    equal :: Eq a => IntMap a -> IntMap a -> Bool
    equal :: forall a. Eq a => IntMap a -> IntMap a -> Bool
    equal (Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) (Bin Int
    p2 Int
    m2 IntMap a
    l2 IntMap a
    r2)
      = (Int
    m1 forall a. Eq a => a -> a -> Bool
    == Int
    m2) Bool -> Bool -> Bool
    && (Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2) Bool -> Bool -> Bool
    && (forall a. Eq a => IntMap a -> IntMap a -> Bool
    equal IntMap a
    l1 IntMap a
    l2) Bool -> Bool -> Bool
    && (forall a. Eq a => IntMap a -> IntMap a -> Bool
    equal IntMap a
    r1 IntMap a
    r2)
    equal (Tip Int
    kx a
    x) (Tip Int
    ky a
    y)
      = (Int
    kx forall a. Eq a => a -> a -> Bool
    == Int
    ky) Bool -> Bool -> Bool
    && (a
    xforall a. Eq a => a -> a -> Bool
    ==a
    y)
    equal IntMap a
    Nil IntMap a
    Nil = Bool
    True
    equal IntMap a
    _   IntMap a
    _   = Bool
    False

    nequal :: Eq a => IntMap a -> IntMap a -> Bool
    nequal :: forall a. Eq a => IntMap a -> IntMap a -> Bool
    nequal (Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) (Bin Int
    p2 Int
    m2 IntMap a
    l2 IntMap a
    r2)
      = (Int
    m1 forall a. Eq a => a -> a -> Bool
    /= Int
    m2) Bool -> Bool -> Bool
    || (Int
    p1 forall a. Eq a => a -> a -> Bool
    /= Int
    p2) Bool -> Bool -> Bool
    || (forall a. Eq a => IntMap a -> IntMap a -> Bool
    nequal IntMap a
    l1 IntMap a
    l2) Bool -> Bool -> Bool
    || (forall a. Eq a => IntMap a -> IntMap a -> Bool
    nequal IntMap a
    r1 IntMap a
    r2)
    nequal (Tip Int
    kx a
    x) (Tip Int
    ky a
    y)
      = (Int
    kx forall a. Eq a => a -> a -> Bool
    /= Int
    ky) Bool -> Bool -> Bool
    || (a
    xforall a. Eq a => a -> a -> Bool
    /=a
    y)
    nequal IntMap a
    Nil IntMap a
    Nil = Bool
    False
    nequal IntMap a
    _   IntMap a
    _   = Bool
    True

    #if MIN_VERSION_base(4,9,0)
    -- | @since 0.5.9
    instance Eq1 IntMap where
      liftEq :: forall a b. (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
    liftEq a -> b -> Bool
    eq (Bin Int
    p1 Int
    m1 IntMap a
    l1 IntMap a
    r1) (Bin Int
    p2 Int
    m2 IntMap b
    l2 IntMap b
    r2)
        = (Int
    m1 forall a. Eq a => a -> a -> Bool
    == Int
    m2) Bool -> Bool -> Bool
    && (Int
    p1 forall a. Eq a => a -> a -> Bool
    == Int
    p2) Bool -> Bool -> Bool
    && (forall (f :: * -> *) a b.
    Eq1 f =>
    (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq a -> b -> Bool
    eq IntMap a
    l1 IntMap b
    l2) Bool -> Bool -> Bool
    && (forall (f :: * -> *) a b.
    Eq1 f =>
    (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq a -> b -> Bool
    eq IntMap a
    r1 IntMap b
    r2)
      liftEq a -> b -> Bool
    eq (Tip Int
    kx a
    x) (Tip Int
    ky b
    y)
        = (Int
    kx forall a. Eq a => a -> a -> Bool
    == Int
    ky) Bool -> Bool -> Bool
    && (a -> b -> Bool
    eq a
    x b
    y)
      liftEq a -> b -> Bool
    _eq IntMap a
    Nil IntMap b
    Nil = Bool
    True
      liftEq a -> b -> Bool
    _eq IntMap a
    _   IntMap b
    _   = Bool
    False
    #endif

    {--------------------------------------------------------------------
      Ord
    --------------------------------------------------------------------}

    instance Ord a => Ord (IntMap a) where
        compare :: IntMap a -> IntMap a -> Ordering
    compare IntMap a
    m1 IntMap a
    m2 = forall a. Ord a => a -> a -> Ordering
    compare (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    m1) (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    m2)

    #if MIN_VERSION_base(4,9,0)
    -- | @since 0.5.9
    instance Ord1 IntMap where
      liftCompare :: forall a b.
    (a -> b -> Ordering) -> IntMap a -> IntMap b -> Ordering
    liftCompare a -> b -> Ordering
    cmp IntMap a
    m IntMap b
    n =
        forall (f :: * -> *) a b.
    Ord1 f =>
    (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare (forall (f :: * -> *) a b.
    Ord1 f =>
    (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare a -> b -> Ordering
    cmp) (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    m) (forall a. IntMap a -> [(Int, a)]
    toList IntMap b
    n)
    #endif

    {--------------------------------------------------------------------
      Functor
    --------------------------------------------------------------------}

    instance Functor IntMap where
        fmap :: forall a b. (a -> b) -> IntMap a -> IntMap b
    fmap = forall a b. (a -> b) -> IntMap a -> IntMap b
    map

    #ifdef __GLASGOW_HASKELL__
        a
    a <$ :: forall a b. a -> IntMap b -> IntMap a
    <$ Bin Int
    p Int
    m IntMap b
    l IntMap b
    r = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m (a
    a forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ IntMap b
    l) (a
    a forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ IntMap b
    r)
        a
    a <$ Tip Int
    k b
    _     = forall a. Int -> a -> IntMap a
    Tip Int
    k a
    a
        a
    _ <$ IntMap b
    Nil         = forall a. IntMap a
    Nil
    #endif

    {--------------------------------------------------------------------
      Show
    --------------------------------------------------------------------}

    instance Show a => Show (IntMap a) where
      showsPrec :: Int -> IntMap a -> ShowS
    showsPrec Int
    d IntMap a
    m   = Bool -> ShowS -> ShowS
    showParen (Int
    d forall a. Ord a => a -> a -> Bool
    > Int
    10) forall a b. (a -> b) -> a -> b
    $
        [Char] -> ShowS
    showString [Char]
    "fromList " forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Show a => a -> ShowS
    shows (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    m)

    #if MIN_VERSION_base(4,9,0)
    -- | @since 0.5.9
    instance Show1 IntMap where
        liftShowsPrec :: forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> IntMap a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl Int
    d IntMap a
    m =
            forall a. (Int -> a -> ShowS) -> [Char] -> Int -> a -> ShowS
    showsUnaryWith (forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec Int -> (Int, a) -> ShowS
    sp' [(Int, a)] -> ShowS
    sl') [Char]
    "fromList" Int
    d (forall a. IntMap a -> [(Int, a)]
    toList IntMap a
    m)
          where
            sp' :: Int -> (Int, a) -> ShowS
    sp' = forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl
            sl' :: [(Int, a)] -> ShowS
    sl' = forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS
    liftShowList Int -> a -> ShowS
    sp [a] -> ShowS
    sl
    #endif

    {--------------------------------------------------------------------
      Read
    --------------------------------------------------------------------}
    instance (Read e) => Read (IntMap e) where
    #ifdef __GLASGOW_HASKELL__
      readPrec :: ReadPrec (IntMap e)
    readPrec = forall a. ReadPrec a -> ReadPrec a
    parens forall a b. (a -> b) -> a -> b
    $ forall a. Int -> ReadPrec a -> ReadPrec a
    prec Int
    10 forall a b. (a -> b) -> a -> b
    $ do
        Ident [Char]
    "fromList" <- ReadPrec Lexeme
    lexP
        [(Int, e)]
    xs <- forall a. Read a => ReadPrec a
    readPrec
        forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a. [(Int, a)] -> IntMap a
    fromList [(Int, e)]
    xs)

      readListPrec :: ReadPrec [IntMap e]
    readListPrec = forall a. Read a => ReadPrec [a]
    readListPrecDefault
    #else
      readsPrec p = readParen (p > 10) $ \ r -> do
        ("fromList",s) <- lex r
        (xs,t) <- reads s
        return (fromList xs,t)
    #endif

    #if MIN_VERSION_base(4,9,0)
    -- | @since 0.5.9
    instance Read1 IntMap where
        liftReadsPrec :: forall a. (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (IntMap a)
    liftReadsPrec Int -> ReadS a
    rp ReadS [a]
    rl = forall a. ([Char] -> ReadS a) -> Int -> ReadS a
    readsData forall a b. (a -> b) -> a -> b
    $
            forall a t.
    (Int -> ReadS a) -> [Char] -> (a -> t) -> [Char] -> ReadS t
    readsUnaryWith (forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
    liftReadsPrec Int -> ReadS (Int, a)
    rp' ReadS [(Int, a)]
    rl') [Char]
    "fromList" forall a. [(Int, a)] -> IntMap a
    fromList
          where
            rp' :: Int -> ReadS (Int, a)
    rp' = forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
    liftReadsPrec Int -> ReadS a
    rp ReadS [a]
    rl
            rl' :: ReadS [(Int, a)]
    rl' = forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> ReadS [f a]
    liftReadList Int -> ReadS a
    rp ReadS [a]
    rl
    #endif

    {--------------------------------------------------------------------
      Typeable
    --------------------------------------------------------------------}

    INSTANCE_TYPEABLE1(IntMap)

    {--------------------------------------------------------------------
      Helpers
    --------------------------------------------------------------------}
    {--------------------------------------------------------------------
      Link
    --------------------------------------------------------------------}
    link :: Prefix -> IntMap a -> Prefix -> IntMap a -> IntMap a
    link :: forall a. Int -> IntMap a -> Int -> IntMap a -> IntMap a
    link Int
    p1 IntMap a
    t1 Int
    p2 IntMap a
    t2 = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask (Int -> Int -> Int
    branchMask Int
    p1 Int
    p2) Int
    p1 IntMap a
    t1 {-p2-} IntMap a
    t2
    {-# INLINE link #-}

    -- `linkWithMask` is useful when the `branchMask` has already been computed
    linkWithMask :: Mask -> Prefix -> IntMap a -> IntMap a -> IntMap a
    linkWithMask :: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    linkWithMask Int
    m Int
    p1 IntMap a
    t1 {-p2-} IntMap a
    t2
      | Int -> Int -> Bool
    zero Int
    p1 Int
    m = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    t1 IntMap a
    t2
      | Bool
    otherwise = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    t2 IntMap a
    t1
      where
        p :: Int
    p = Int -> Int -> Int
    mask Int
    p1 Int
    m
    {-# INLINE linkWithMask #-}

    {--------------------------------------------------------------------
      @bin@ assures that we never have empty trees within a tree.
    --------------------------------------------------------------------}
    bin :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
    bin :: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    bin Int
    _ Int
    _ IntMap a
    l IntMap a
    Nil = IntMap a
    l
    bin Int
    _ Int
    _ IntMap a
    Nil IntMap a
    r = IntMap a
    r
    bin Int
    p Int
    m IntMap a
    l IntMap a
    r   = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l IntMap a
    r
    {-# INLINE bin #-}

    -- binCheckLeft only checks that the left subtree is non-empty
    binCheckLeft :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft :: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckLeft Int
    _ Int
    _ IntMap a
    Nil IntMap a
    r = IntMap a
    r
    binCheckLeft Int
    p Int
    m IntMap a
    l IntMap a
    r   = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l IntMap a
    r
    {-# INLINE binCheckLeft #-}

    -- binCheckRight only checks that the right subtree is non-empty
    binCheckRight :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
    binCheckRight :: forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    binCheckRight Int
    _ Int
    _ IntMap a
    l IntMap a
    Nil = IntMap a
    l
    binCheckRight Int
    p Int
    m IntMap a
    l IntMap a
    r   = forall a. Int -> Int -> IntMap a -> IntMap a -> IntMap a
    Bin Int
    p Int
    m IntMap a
    l IntMap a
    r
    {-# INLINE binCheckRight #-}

    {--------------------------------------------------------------------
      Endian independent bit twiddling
    --------------------------------------------------------------------}

    -- | Should this key follow the left subtree of a 'Bin' with switching
    -- bit @m@? N.B., the answer is only valid when @match i p m@ is true.
    zero :: Key -> Mask -> Bool
    zero :: Int -> Int -> Bool
    zero Int
    i Int
    m
      = (Int -> Nat
    natFromInt Int
    i) forall a. Bits a => a -> a -> a
    .&. (Int -> Nat
    natFromInt Int
    m) forall a. Eq a => a -> a -> Bool
    == Nat
    0
    {-# INLINE zero #-}

    nomatch,match :: Key -> Prefix -> Mask -> Bool

    -- | Does the key @i@ differ from the prefix @p@ before getting to
    -- the switching bit @m@?
    nomatch :: Int -> Int -> Int -> Bool
    nomatch Int
    i Int
    p Int
    m
      = (Int -> Int -> Int
    mask Int
    i Int
    m) forall a. Eq a => a -> a -> Bool
    /= Int
    p
    {-# INLINE nomatch #-}

    -- | Does the key @i@ match the prefix @p@ (up to but not including
    -- bit @m@)?
    match :: Int -> Int -> Int -> Bool
    match Int
    i Int
    p Int
    m
      = (Int -> Int -> Int
    mask Int
    i Int
    m) forall a. Eq a => a -> a -> Bool
    == Int
    p
    {-# INLINE match #-}

    -- | The prefix of key @i@ up to (but not including) the switching
    -- bit @m@.
    mask :: Key -> Mask -> Prefix
    mask :: Int -> Int -> Int
    mask Int
    i Int
    m
      = Nat -> Nat -> Int
    maskW (Int -> Nat
    natFromInt Int
    i) (Int -> Nat
    natFromInt Int
    m)
    {-# INLINE mask #-}

    {--------------------------------------------------------------------
      Big endian operations
    --------------------------------------------------------------------}

    -- | The prefix of key @i@ up to (but not including) the switching
    -- bit @m@.
    maskW :: Nat -> Nat -> Prefix
    maskW :: Nat -> Nat -> Int
    maskW Nat
    i Nat
    m
      = Nat -> Int
    intFromNat (Nat
    i forall a. Bits a => a -> a -> a
    .&. ((-Nat
    m) forall a. Bits a => a -> a -> a
    `xor` Nat
    m))
    {-# INLINE maskW #-}

    -- | Does the left switching bit specify a shorter prefix?
    shorter :: Mask -> Mask -> Bool
    shorter :: Int -> Int -> Bool
    shorter Int
    m1 Int
    m2
      = (Int -> Nat
    natFromInt Int
    m1) forall a. Ord a => a -> a -> Bool
    > (Int -> Nat
    natFromInt Int
    m2)
    {-# INLINE shorter #-}

    -- | The first switching bit where the two prefixes disagree.
    branchMask :: Prefix -> Prefix -> Mask
    branchMask :: Int -> Int -> Int
    branchMask Int
    p1 Int
    p2
      = Nat -> Int
    intFromNat (Nat -> Nat
    highestBitMask (Int -> Nat
    natFromInt Int
    p1 forall a. Bits a => a -> a -> a
    `xor` Int -> Nat
    natFromInt Int
    p2))
    {-# INLINE branchMask #-}

    {--------------------------------------------------------------------
      Utilities
    --------------------------------------------------------------------}

    -- | /O(1)/.  Decompose a map into pieces based on the structure
    -- of the underlying tree. This function is useful for consuming a
    -- map in parallel.
    --
    -- No guarantee is made as to the sizes of the pieces; an internal, but
    -- deterministic process determines this.  However, it is guaranteed that the
    -- pieces returned will be in ascending order (all elements in the first submap
    -- less than all elements in the second, and so on).
    --
    -- Examples:
    --
    -- > splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
    -- >   [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
    --
    -- > splitRoot empty == []
    --
    --  Note that the current implementation does not return more than two submaps,
    --  but you should not depend on this behaviour because it can change in the
    --  future without notice.
    splitRoot :: IntMap a -> [IntMap a]
    splitRoot :: forall a. IntMap a -> [IntMap a]
    splitRoot IntMap a
    orig =
      case IntMap a
    orig of
        IntMap a
    Nil -> []
        x :: IntMap a
    x@(Tip Int
    _ a
    _) -> [IntMap a
    x]
        Bin Int
    _ Int
    m IntMap a
    l IntMap a
    r | Int
    m forall a. Ord a => a -> a -> Bool
    < Int
    0 -> [IntMap a
    r, IntMap a
    l]
                    | Bool
    otherwise -> [IntMap a
    l, IntMap a
    r]
    {-# INLINE splitRoot #-}

    {--------------------------------------------------------------------
      Debugging
    --------------------------------------------------------------------}

    -- | /O(n)/. Show the tree that implements the map. The tree is shown
    -- in a compressed, hanging format.
    showTree :: Show a => IntMap a -> String
    showTree :: forall a. Show a => IntMap a -> [Char]
    showTree IntMap a
    s
      = forall a. Show a => Bool -> Bool -> IntMap a -> [Char]
    showTreeWith Bool
    True Bool
    False IntMap a
    s

    {- | /O(n)/. The expression (@'showTreeWith' hang wide map@) shows
     the tree that implements the map. If @hang@ is
     'True', a /hanging/ tree is shown otherwise a rotated tree is shown. If
     @wide@ is 'True', an extra wide version is shown.
    -}
    showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String
    showTreeWith :: forall a. Show a => Bool -> Bool -> IntMap a -> [Char]
    showTreeWith Bool
    hang Bool
    wide IntMap a
    t
      | Bool
    hang      = (forall a. Show a => Bool -> [[Char]] -> IntMap a -> ShowS
    showsTreeHang Bool
    wide [] IntMap a
    t) [Char]
    ""
      | Bool
    otherwise = (forall a.
    Show a =>
    Bool -> [[Char]] -> [[Char]] -> IntMap a -> ShowS
    showsTree Bool
    wide [] [] IntMap a
    t) [Char]
    ""

    showsTree :: Show a => Bool -> [String] -> [String] -> IntMap a -> ShowS
    showsTree :: forall a.
    Show a =>
    Bool -> [[Char]] -> [[Char]] -> IntMap a -> ShowS
    showsTree Bool
    wide [[Char]]
    lbars [[Char]]
    rbars IntMap a
    t = case IntMap a
    t of
      Bin Int
    p Int
    m IntMap a
    l IntMap a
    r ->
        forall a.
    Show a =>
    Bool -> [[Char]] -> [[Char]] -> IntMap a -> ShowS
    showsTree Bool
    wide ([[Char]] -> [[Char]]
    withBar [[Char]]
    rbars) ([[Char]] -> [[Char]]
    withEmpty [[Char]]
    rbars) IntMap a
    r forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    rbars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        [[Char]] -> ShowS
    showsBars [[Char]]
    lbars forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString (Int -> Int -> [Char]
    showBin Int
    p Int
    m) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    lbars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        forall a.
    Show a =>
    Bool -> [[Char]] -> [[Char]] -> IntMap a -> ShowS
    showsTree Bool
    wide ([[Char]] -> [[Char]]
    withEmpty [[Char]]
    lbars) ([[Char]] -> [[Char]]
    withBar [[Char]]
    lbars) IntMap a
    l
      Tip Int
    k a
    x ->
        [[Char]] -> ShowS
    showsBars [[Char]]
    lbars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        [Char] -> ShowS
    showString [Char]
    " " forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Show a => a -> ShowS
    shows Int
    k forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    ":=" forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Show a => a -> ShowS
    shows a
    x forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n"
      IntMap a
    Nil -> [[Char]] -> ShowS
    showsBars [[Char]]
    lbars forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "|\n"

    showsTreeHang :: Show a => Bool -> [String] -> IntMap a -> ShowS
    showsTreeHang :: forall a. Show a => Bool -> [[Char]] -> IntMap a -> ShowS
    showsTreeHang Bool
    wide [[Char]]
    bars IntMap a
    t = case IntMap a
    t of
      Bin Int
    p Int
    m IntMap a
    l IntMap a
    r ->
        [[Char]] -> ShowS
    showsBars [[Char]]
    bars forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString (Int -> Int -> [Char]
    showBin Int
    p Int
    m) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    bars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        forall a. Show a => Bool -> [[Char]] -> IntMap a -> ShowS
    showsTreeHang Bool
    wide ([[Char]] -> [[Char]]
    withBar [[Char]]
    bars) IntMap a
    l forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    bars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        forall a. Show a => Bool -> [[Char]] -> IntMap a -> ShowS
    showsTreeHang Bool
    wide ([[Char]] -> [[Char]]
    withEmpty [[Char]]
    bars) IntMap a
    r
      Tip Int
    k a
    x ->
        [[Char]] -> ShowS
    showsBars [[Char]]
    bars forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        [Char] -> ShowS
    showString [Char]
    " " forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Show a => a -> ShowS
    shows Int
    k forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    ":=" forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Show a => a -> ShowS
    shows a
    x forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n"
      IntMap a
    Nil -> [[Char]] -> ShowS
    showsBars [[Char]]
    bars forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "|\n"

    showBin :: Prefix -> Mask -> String
    showBin :: Int -> Int -> [Char]
    showBin Int
    _ Int
    _
      = [Char]
    "*" -- ++ show (p,m)

    showWide :: Bool -> [String] -> String -> String
    showWide :: Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    bars
      | Bool
    wide      = [Char] -> ShowS
    showString (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat (forall a. [a] -> [a]
    reverse [[Char]]
    bars)) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "|\n"
      | Bool
    otherwise = forall a. a -> a
    id

    showsBars :: [String] -> ShowS
    showsBars :: [[Char]] -> ShowS
    showsBars [[Char]]
    bars
      = case [[Char]]
    bars of
          [] -> forall a. a -> a
    id
          [[Char]]
    _  -> [Char] -> ShowS
    showString (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat (forall a. [a] -> [a]
    reverse (forall a. [a] -> [a]
    tail [[Char]]
    bars))) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    node

    node :: String
    node :: [Char]
    node = [Char]
    "+--"

    withBar, withEmpty :: [String] -> [String]
    withBar :: [[Char]] -> [[Char]]
    withBar [[Char]]
    bars   = [Char]
    "|  "forall a. a -> [a] -> [a]
    :[[Char]]
    bars
    withEmpty :: [[Char]] -> [[Char]]
    withEmpty [[Char]]
    bars = [Char]
    "   "forall a. a -> [a] -> [a]
    :[[Char]]
    bars