    {-# LANGUAGE CPP #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE PatternGuards #-}
    #if !defined(TESTING) && defined(__GLASGOW_HASKELL__)
    {-# LANGUAGE Trustworthy #-}
    #endif
    #ifdef __GLASGOW_HASKELL__
    {-# LANGUAGE DeriveLift #-}
    {-# LANGUAGE RoleAnnotations #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE TypeFamilies #-}
    #endif

    {-# OPTIONS_HADDOCK not-home #-}

    #include "containers.h"

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Set.Internal
    -- Copyright   :  (c) Daan Leijen 2002
    -- 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
    --
    -- An efficient implementation of sets.
    --
    -- These modules are intended to be imported qualified, to avoid name
    -- clashes with Prelude functions, e.g.
    --
    -- >  import Data.Set (Set)
    -- >  import qualified Data.Set as Set
    --
    -- The implementation of 'Set' is based on /size balanced/ binary trees (or
    -- trees of /bounded balance/) as described by:
    --
    --    * Stephen Adams, \"/Efficient sets: a balancing act/\",
    --      Journal of Functional Programming 3(4):553-562, October 1993,
    --      <http://www.swiss.ai.mit.edu/~adams/BB/>.
    --    * J. Nievergelt and E.M. Reingold,
    --      \"/Binary search trees of bounded balance/\",
    --      SIAM journal of computing 2(1), March 1973.
    --
    --  Bounds for 'union', 'intersection', and 'difference' are as given
    --  by
    --
    --    * Guy Blelloch, Daniel Ferizovic, and Yihan Sun,
    --      \"/Just Join for Parallel Ordered Sets/\",
    --      <https://arxiv.org/abs/1602.02120v3>.
    --
    -- Note that the implementation is /left-biased/ -- the elements of a
    -- first argument are always preferred to the second, for example in
    -- 'union' or 'insert'.  Of course, left-biasing can only be observed
    -- when equality is an equivalence relation instead of structural
    -- equality.
    --
    -- /Warning/: The size of the set must not exceed @maxBound::Int@. Violation of
    -- this condition is not detected and if the size limit is exceeded, the
    -- behavior of the set is completely undefined.
    --
    -- @since 0.5.9
    -----------------------------------------------------------------------------

    -- [Note: Using INLINABLE]
    -- ~~~~~~~~~~~~~~~~~~~~~~~
    -- It is crucial to the performance that the functions specialize on the Ord
    -- type when possible. GHC 7.0 and higher does this by itself when it sees th
    -- unfolding of a function -- that is why all public functions are marked
    -- INLINABLE (that exposes the unfolding).

    -- [Note: Using INLINE]
    -- ~~~~~~~~~~~~~~~~~~~~
    -- For other compilers and GHC pre 7.0, we mark some of the functions INLINE.
    -- We mark the functions that just navigate down the tree (lookup, insert,
    -- delete and similar). That navigation code gets inlined and thus specialized
    -- when possible. There is a price to pay -- code growth. The code INLINED is
    -- therefore only the tree navigation, all the real work (rebalancing) is not
    -- INLINED by using a NOINLINE.
    --
    -- All methods marked INLINE have to be nonrecursive -- a 'go' function doing
    -- the real work is provided.

    -- [Note: Type of local 'go' function]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- If the local 'go' function uses an Ord class, it sometimes heap-allocates
    -- the Ord dictionary when the 'go' function does not have explicit type.
    -- In that case we give 'go' explicit type. But this slightly decrease
    -- performance, as the resulting 'go' function can float out to top level.

    -- [Note: Local 'go' functions and capturing]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- As opposed to IntSet, when 'go' function captures an argument, increased
    -- heap-allocation can occur: sometimes in a polymorphic function, the 'go'
    -- floats out of its enclosing function and then it heap-allocates the
    -- dictionary and the argument. Maybe it floats out too late and strictness
    -- analyzer cannot see that these could be passed on stack.

    -- [Note: Order of constructors]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- The order of constructors of Set matters when considering performance.
    -- Currently in GHC 7.0, when type has 2 constructors, a forward conditional
    -- jump is made when successfully matching second constructor. Successful match
    -- of first constructor results in the forward jump not taken.
    -- On GHC 7.0, reordering constructors from Tip | Bin to Bin | Tip
    -- improves the benchmark by up to 10% on x86.

    module Data.Set.Internal (
                -- * Set type
                  Set(..)       -- instance Eq,Ord,Show,Read,Data
                , Size

                -- * Operators
                , (\\)

                -- * Query
                , null
                , size
                , member
                , notMember
                , lookupLT
                , lookupGT
                , lookupLE
                , lookupGE
                , isSubsetOf
                , isProperSubsetOf
                , disjoint

                -- * Construction
                , empty
                , singleton
                , insert
                , delete
                , alterF
                , powerSet

                -- * Combine
                , union
                , unions
                , difference
                , intersection
                , intersections
                , cartesianProduct
                , disjointUnion
                , Intersection(..)

                -- * Filter
                , filter
                , takeWhileAntitone
                , dropWhileAntitone
                , spanAntitone
                , partition
                , split
                , splitMember
                , splitRoot

                -- * Indexed
                , lookupIndex
                , findIndex
                , elemAt
                , deleteAt
                , take
                , drop
                , splitAt

                -- * Map
                , map
                , mapMonotonic

                -- * Folds
                , foldr
                , foldl
                -- ** Strict folds
                , foldr'
                , foldl'
                -- ** Legacy folds
                , fold

                -- * Min\/Max
                , lookupMin
                , lookupMax
                , findMin
                , findMax
                , deleteMin
                , deleteMax
                , deleteFindMin
                , deleteFindMax
                , maxView
                , minView

                -- * Conversion

                -- ** List
                , elems
                , toList
                , fromList

                -- ** Ordered list
                , toAscList
                , toDescList
                , fromAscList
                , fromDistinctAscList
                , fromDescList
                , fromDistinctDescList

                -- * Debugging
                , showTree
                , showTreeWith
                , valid

                -- Internals (for testing)
                , bin
                , balanced
                , link
                , merge
                ) where

    import Utils.Containers.Internal.Prelude hiding
      (filter,foldl,foldr,null,map,take,drop,splitAt)
    import Prelude ()
    import Control.Applicative (Const(..))
    import qualified Data.List as List
    import Data.Bits (shiftL, shiftR)
    import Data.Semigroup (Semigroup(stimes))
    import Data.List.NonEmpty (NonEmpty(..))
    #if !(MIN_VERSION_base(4,11,0))
    import Data.Semigroup (Semigroup((<>)))
    #endif
    import Data.Semigroup (stimesIdempotentMonoid, stimesIdempotent)
    import Data.Functor.Classes
    import Data.Functor.Identity (Identity)
    import qualified Data.Foldable as Foldable
    import Control.DeepSeq (NFData(rnf))

    import Utils.Containers.Internal.StrictPair
    import Utils.Containers.Internal.PtrEquality

    #if __GLASGOW_HASKELL__
    import GHC.Exts ( build, lazy )
    import qualified GHC.Exts as GHCExts
    import Text.Read ( readPrec, Read (..), Lexeme (..), parens, prec
                     , lexP, readListPrecDefault )
    import Data.Data
    import Language.Haskell.TH.Syntax (Lift)
    -- See Note [ Template Haskell Dependencies ]
    import Language.Haskell.TH ()
    #endif

    {--------------------------------------------------------------------
      Operators
    --------------------------------------------------------------------}
    infixl 9 \\ --

    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). See 'difference'.
    (\\) :: Ord a => Set a -> Set a -> Set a
    Set a
    m1 \\ :: forall a. Ord a => Set a -> Set a -> Set a
    \\ Set a
    m2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    difference Set a
    m1 Set a
    m2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE (\\) #-}
    #endif

    {--------------------------------------------------------------------
      Sets are size balanced trees
    --------------------------------------------------------------------}
    -- | A set of values @a@.

    -- See Note: Order of constructors
    data Set a    = Bin {-# UNPACK #-} !Size !a !(Set a) !(Set a)
                  | Tip

    type Size     = Int

    #ifdef __GLASGOW_HASKELL__
    type role Set nominal
    #endif

    -- | @since 0.6.6
    deriving instance Lift a => Lift (Set a)

    instance Ord a => Monoid (Set a) where
        mempty :: Set a
    mempty  = Set a
    forall a. Set a
    empty
        mconcat :: [Set a] -> Set a
    mconcat = [Set a] -> Set a
    forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
    unions
        mappend :: Set a -> Set a -> Set a
    mappend = Set a -> Set a -> Set a
    forall a. Semigroup a => a -> a -> a
    (<>)

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

    -- | Folds in order of increasing key.
    instance Foldable.Foldable Set where
        fold :: forall m. Monoid m => Set m -> m
    fold = Set m -> m
    forall m. Monoid m => Set m -> m
    go
          where go :: Set a -> a
    go Set a
    Tip = a
    forall a. Monoid a => a
    mempty
                go (Bin Size
    1 a
    k Set a
    _ Set a
    _) = a
    k
                go (Bin Size
    _ a
    k Set a
    l Set a
    r) = Set a -> a
    go Set a
    l a -> a -> a
    forall a. Monoid a => a -> a -> a
    `mappend` (a
    k a -> a -> a
    forall a. Monoid a => a -> a -> a
    `mappend` Set a -> a
    go Set a
    r)
        {-# INLINABLE fold #-}
        foldr :: forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr = (a -> b -> b) -> b -> Set a -> b
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr
        {-# INLINE foldr #-}
        foldl :: forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl = (b -> a -> b) -> b -> Set a -> b
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl
        {-# INLINE foldl #-}
        foldMap :: forall m a. Monoid m => (a -> m) -> Set a -> m
    foldMap a -> m
    f Set a
    t = Set a -> m
    go Set a
    t
          where go :: Set a -> m
    go Set a
    Tip = m
    forall a. Monoid a => a
    mempty
                go (Bin Size
    1 a
    k Set a
    _ Set a
    _) = a -> m
    f a
    k
                go (Bin Size
    _ a
    k Set a
    l Set a
    r) = Set a -> m
    go Set a
    l m -> m -> m
    forall a. Monoid a => a -> a -> a
    `mappend` (a -> m
    f a
    k m -> m -> m
    forall a. Monoid a => a -> a -> a
    `mappend` Set a -> m
    go Set a
    r)
        {-# INLINE foldMap #-}
        foldl' :: forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl' = (b -> a -> b) -> b -> Set a -> b
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl'
        {-# INLINE foldl' #-}
        foldr' :: forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr' = (a -> b -> b) -> b -> Set a -> b
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr'
        {-# INLINE foldr' #-}
        length :: forall a. Set a -> Size
    length = Set a -> Size
    forall a. Set a -> Size
    size
        {-# INLINE length #-}
        null :: forall a. Set a -> Bool
    null   = Set a -> Bool
    forall a. Set a -> Bool
    null
        {-# INLINE null #-}
        toList :: forall a. Set a -> [a]
    toList = Set a -> [a]
    forall a. Set a -> [a]
    toList
        {-# INLINE toList #-}
        elem :: forall a. Eq a => a -> Set a -> Bool
    elem = a -> Set a -> Bool
    forall a. Eq a => a -> Set a -> Bool
    go
          where go :: t -> Set t -> Bool
    go !t
    _ Set t
    Tip = Bool
    False
                go t
    x (Bin Size
    _ t
    y Set t
    l Set t
    r) = t
    x t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    y Bool -> Bool -> Bool
    || t -> Set t -> Bool
    go t
    x Set t
    l Bool -> Bool -> Bool
    || t -> Set t -> Bool
    go t
    x Set t
    r
        {-# INLINABLE elem #-}
        minimum :: forall a. Ord a => Set a -> a
    minimum = Set a -> a
    forall a. Set a -> a
    findMin
        {-# INLINE minimum #-}
        maximum :: forall a. Ord a => Set a -> a
    maximum = Set a -> a
    forall a. Set a -> a
    findMax
        {-# INLINE maximum #-}
        sum :: forall a. Num a => Set a -> a
    sum = (a -> a -> a) -> a -> Set a -> a
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl' a -> a -> a
    forall a. Num a => a -> a -> a
    (+) a
    0
        {-# INLINABLE sum #-}
        product :: forall a. Num a => Set a -> a
    product = (a -> a -> a) -> a -> Set a -> a
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl' a -> a -> a
    forall a. Num a => a -> a -> a
    (*) a
    1
        {-# INLINABLE product #-}

    #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, Ord a) => Data (Set a) where
      gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Set a -> c (Set a)
    gfoldl forall d b. Data d => c (d -> b) -> d -> c b
    f forall g. g -> c g
    z Set a
    set = ([a] -> Set a) -> c ([a] -> Set a)
    forall g. g -> c g
    z [a] -> Set a
    forall a. Ord a => [a] -> Set a
    fromList c ([a] -> Set a) -> [a] -> c (Set a)
    forall d b. Data d => c (d -> b) -> d -> c b
    `f` (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    set)
      toConstr :: Set a -> Constr
    toConstr Set a
    _     = Constr
    fromListConstr
      gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Set a)
    gunfold forall b r. Data b => c (b -> r) -> c r
    k forall r. r -> c r
    z Constr
    c  = case Constr -> Size
    constrIndex Constr
    c of
        Size
    1 -> c ([a] -> Set a) -> c (Set a)
    forall b r. Data b => c (b -> r) -> c r
    k (([a] -> Set a) -> c ([a] -> Set a)
    forall r. r -> c r
    z [a] -> Set a
    forall a. Ord a => [a] -> Set a
    fromList)
        Size
    _ -> [Char] -> c (Set a)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "gunfold"
      dataTypeOf :: Set a -> DataType
    dataTypeOf Set a
    _   = DataType
    setDataType
      dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Set a))
    dataCast1 forall d. Data d => c (t d)
    f    = c (t a) -> Maybe (c (Set a))
    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 c (t a)
    forall d. Data d => c (t d)
    f

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

    setDataType :: DataType
    setDataType :: DataType
    setDataType = [Char] -> [Constr] -> DataType
    mkDataType [Char]
    "Data.Set.Internal.Set" [Constr
    fromListConstr]

    #endif

    {--------------------------------------------------------------------
      Query
    --------------------------------------------------------------------}
    -- | \(O(1)\). Is this the empty set?
    null :: Set a -> Bool
    null :: forall a. Set a -> Bool
    null Set a
    Tip      = Bool
    True
    null (Bin {}) = Bool
    False
    {-# INLINE null #-}

    -- | \(O(1)\). The number of elements in the set.
    size :: Set a -> Int
    size :: forall a. Set a -> Size
    size Set a
    Tip = Size
    0
    size (Bin Size
    sz a
    _ Set a
    _ Set a
    _) = Size
    sz
    {-# INLINE size #-}

    -- | \(O(\log n)\). Is the element in the set?
    member :: Ord a => a -> Set a -> Bool
    member :: forall a. Ord a => a -> Set a -> Bool
    member = a -> Set a -> Bool
    forall a. Ord a => a -> Set a -> Bool
    go
      where
        go :: t -> Set t -> Bool
    go !t
    _ Set t
    Tip = Bool
    False
        go t
    x (Bin Size
    _ t
    y Set t
    l Set t
    r) = case t -> t -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare t
    x t
    y of
          Ordering
    LT -> t -> Set t -> Bool
    go t
    x Set t
    l
          Ordering
    GT -> t -> Set t -> Bool
    go t
    x Set t
    r
          Ordering
    EQ -> Bool
    True
    #if __GLASGOW_HASKELL__
    {-# INLINABLE member #-}
    #else
    {-# INLINE member #-}
    #endif

    -- | \(O(\log n)\). Is the element not in the set?
    notMember :: Ord a => a -> Set a -> Bool
    notMember :: forall a. Ord a => a -> Set a -> Bool
    notMember a
    a Set a
    t = Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ a -> Set a -> Bool
    forall a. Ord a => a -> Set a -> Bool
    member a
    a Set a
    t
    #if __GLASGOW_HASKELL__
    {-# INLINABLE notMember #-}
    #else
    {-# INLINE notMember #-}
    #endif

    -- | \(O(\log n)\). Find largest element smaller than the given one.
    --
    -- > lookupLT 3 (fromList [3, 5]) == Nothing
    -- > lookupLT 5 (fromList [3, 5]) == Just 3
    lookupLT :: Ord a => a -> Set a -> Maybe a
    lookupLT :: forall a. Ord a => a -> Set a -> Maybe a
    lookupLT = a -> Set a -> Maybe a
    forall a. Ord a => a -> Set a -> Maybe a
    goNothing
      where
        goNothing :: a -> Set a -> Maybe a
    goNothing !a
    _ Set a
    Tip = Maybe a
    forall a. Maybe a
    Nothing
        goNothing a
    x (Bin Size
    _ a
    y Set a
    l Set a
    r) | a
    x a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    y = a -> Set a -> Maybe a
    goNothing a
    x Set a
    l
                                  | Bool
    otherwise = a -> a -> Set a -> Maybe a
    forall {t}. Ord t => t -> t -> Set t -> Maybe t
    goJust a
    x a
    y Set a
    r

        goJust :: t -> t -> Set t -> Maybe t
    goJust !t
    _ t
    best Set t
    Tip = t -> Maybe t
    forall a. a -> Maybe a
    Just t
    best
        goJust t
    x t
    best (Bin Size
    _ t
    y Set t
    l Set t
    r) | t
    x t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    <= t
    y = t -> t -> Set t -> Maybe t
    goJust t
    x t
    best Set t
    l
                                    | Bool
    otherwise = t -> t -> Set t -> Maybe t
    goJust t
    x t
    y Set t
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE lookupLT #-}
    #else
    {-# INLINE lookupLT #-}
    #endif

    -- | \(O(\log n)\). Find smallest element greater than the given one.
    --
    -- > lookupGT 4 (fromList [3, 5]) == Just 5
    -- > lookupGT 5 (fromList [3, 5]) == Nothing
    lookupGT :: Ord a => a -> Set a -> Maybe a
    lookupGT :: forall a. Ord a => a -> Set a -> Maybe a
    lookupGT = a -> Set a -> Maybe a
    forall a. Ord a => a -> Set a -> Maybe a
    goNothing
      where
        goNothing :: t -> Set t -> Maybe t
    goNothing !t
    _ Set t
    Tip = Maybe t
    forall a. Maybe a
    Nothing
        goNothing t
    x (Bin Size
    _ t
    y Set t
    l Set t
    r) | t
    x t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    < t
    y = t -> t -> Set t -> Maybe t
    forall {t}. Ord t => t -> t -> Set t -> Maybe t
    goJust t
    x t
    y Set t
    l
                                  | Bool
    otherwise = t -> Set t -> Maybe t
    goNothing t
    x Set t
    r

        goJust :: t -> t -> Set t -> Maybe t
    goJust !t
    _ t
    best Set t
    Tip = t -> Maybe t
    forall a. a -> Maybe a
    Just t
    best
        goJust t
    x t
    best (Bin Size
    _ t
    y Set t
    l Set t
    r) | t
    x t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    < t
    y = t -> t -> Set t -> Maybe t
    goJust t
    x t
    y Set t
    l
                                    | Bool
    otherwise = t -> t -> Set t -> Maybe t
    goJust t
    x t
    best Set t
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE lookupGT #-}
    #else
    {-# INLINE lookupGT #-}
    #endif

    -- | \(O(\log n)\). Find largest element smaller or equal to the given one.
    --
    -- > lookupLE 2 (fromList [3, 5]) == Nothing
    -- > lookupLE 4 (fromList [3, 5]) == Just 3
    -- > lookupLE 5 (fromList [3, 5]) == Just 5
    lookupLE :: Ord a => a -> Set a -> Maybe a
    lookupLE :: forall a. Ord a => a -> Set a -> Maybe a
    lookupLE = a -> Set a -> Maybe a
    forall a. Ord a => a -> Set a -> Maybe a
    goNothing
      where
        goNothing :: a -> Set a -> Maybe a
    goNothing !a
    _ Set a
    Tip = Maybe a
    forall a. Maybe a
    Nothing
        goNothing a
    x (Bin Size
    _ a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of Ordering
    LT -> a -> Set a -> Maybe a
    goNothing a
    x Set a
    l
                                                        Ordering
    EQ -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    y
                                                        Ordering
    GT -> a -> a -> Set a -> Maybe a
    forall {t}. Ord t => t -> t -> Set t -> Maybe t
    goJust a
    x a
    y Set a
    r

        goJust :: t -> t -> Set t -> Maybe t
    goJust !t
    _ t
    best Set t
    Tip = t -> Maybe t
    forall a. a -> Maybe a
    Just t
    best
        goJust t
    x t
    best (Bin Size
    _ t
    y Set t
    l Set t
    r) = case t -> t -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare t
    x t
    y of Ordering
    LT -> t -> t -> Set t -> Maybe t
    goJust t
    x t
    best Set t
    l
                                                          Ordering
    EQ -> t -> Maybe t
    forall a. a -> Maybe a
    Just t
    y
                                                          Ordering
    GT -> t -> t -> Set t -> Maybe t
    goJust t
    x t
    y Set t
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE lookupLE #-}
    #else
    {-# INLINE lookupLE #-}
    #endif

    -- | \(O(\log n)\). Find smallest element greater or equal to the given one.
    --
    -- > lookupGE 3 (fromList [3, 5]) == Just 3
    -- > lookupGE 4 (fromList [3, 5]) == Just 5
    -- > lookupGE 6 (fromList [3, 5]) == Nothing
    lookupGE :: Ord a => a -> Set a -> Maybe a
    lookupGE :: forall a. Ord a => a -> Set a -> Maybe a
    lookupGE = a -> Set a -> Maybe a
    forall a. Ord a => a -> Set a -> Maybe a
    goNothing
      where
        goNothing :: t -> Set t -> Maybe t
    goNothing !t
    _ Set t
    Tip = Maybe t
    forall a. Maybe a
    Nothing
        goNothing t
    x (Bin Size
    _ t
    y Set t
    l Set t
    r) = case t -> t -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare t
    x t
    y of Ordering
    LT -> t -> t -> Set t -> Maybe t
    forall {t}. Ord t => t -> t -> Set t -> Maybe t
    goJust t
    x t
    y Set t
    l
                                                        Ordering
    EQ -> t -> Maybe t
    forall a. a -> Maybe a
    Just t
    y
                                                        Ordering
    GT -> t -> Set t -> Maybe t
    goNothing t
    x Set t
    r

        goJust :: a -> a -> Set a -> Maybe a
    goJust !a
    _ a
    best Set a
    Tip = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    best
        goJust a
    x a
    best (Bin Size
    _ a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of Ordering
    LT -> a -> a -> Set a -> Maybe a
    goJust a
    x a
    y Set a
    l
                                                          Ordering
    EQ -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    y
                                                          Ordering
    GT -> a -> a -> Set a -> Maybe a
    goJust a
    x a
    best Set a
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE lookupGE #-}
    #else
    {-# INLINE lookupGE #-}
    #endif

    {--------------------------------------------------------------------
      Construction
    --------------------------------------------------------------------}
    -- | \(O(1)\). The empty set.
    empty  :: Set a
    empty :: forall a. Set a
    empty = Set a
    forall a. Set a
    Tip
    {-# INLINE empty #-}

    -- | \(O(1)\). Create a singleton set.
    singleton :: a -> Set a
    singleton :: forall a. a -> Set a
    singleton a
    x = Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
    {-# INLINE singleton #-}

    {--------------------------------------------------------------------
      Insertion, Deletion
    --------------------------------------------------------------------}
    -- | \(O(\log n)\). Insert an element in a set.
    -- If the set already contains an element equal to the given value,
    -- it is replaced with the new value.

    -- See Note: Type of local 'go' function
    -- See Note: Avoiding worker/wrapper (in Data.Map.Internal)
    insert :: Ord a => a -> Set a -> Set a
    insert :: forall a. Ord a => a -> Set a -> Set a
    insert a
    x0 = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    x0 a
    x0
      where
        go :: Ord a => a -> a -> Set a -> Set a
        go :: forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig !a
    _ Set a
    Tip = a -> Set a
    forall a. a -> Set a
    singleton (a -> a
    forall a. a -> a
    lazy a
    orig)
        go a
    orig !a
    x t :: Set a
    t@(Bin Size
    sz a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
            Ordering
    LT | Set a
    l' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y Set a
    l' Set a
    r
               where !l' :: Set a
    l' = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig a
    x Set a
    l
            Ordering
    GT | Set a
    r' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    l Set a
    r'
               where !r' :: Set a
    r' = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig a
    x Set a
    r
            Ordering
    EQ | a -> a
    forall a. a -> a
    lazy a
    orig a -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` (a
    orig a -> a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` a
    y) -> Set a
    t
               | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    sz (a -> a
    forall a. a -> a
    lazy a
    orig) Set a
    l Set a
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE insert #-}
    #else
    {-# INLINE insert #-}
    #endif

    #ifndef __GLASGOW_HASKELL__
    lazy :: a -> a
    lazy a = a
    #endif

    -- Insert an element to the set only if it is not in the set.
    -- Used by `union`.

    -- See Note: Type of local 'go' function
    -- See Note: Avoiding worker/wrapper (in Data.Map.Internal)
    insertR :: Ord a => a -> Set a -> Set a
    insertR :: forall a. Ord a => a -> Set a -> Set a
    insertR a
    x0 = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    x0 a
    x0
      where
        go :: Ord a => a -> a -> Set a -> Set a
        go :: forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig !a
    _ Set a
    Tip = a -> Set a
    forall a. a -> Set a
    singleton (a -> a
    forall a. a -> a
    lazy a
    orig)
        go a
    orig !a
    x t :: Set a
    t@(Bin Size
    _ a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
            Ordering
    LT | Set a
    l' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y Set a
    l' Set a
    r
               where !l' :: Set a
    l' = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig a
    x Set a
    l
            Ordering
    GT | Set a
    r' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    l Set a
    r'
               where !r' :: Set a
    r' = a -> a -> Set a -> Set a
    forall a. Ord a => a -> a -> Set a -> Set a
    go a
    orig a
    x Set a
    r
            Ordering
    EQ -> Set a
    t
    #if __GLASGOW_HASKELL__
    {-# INLINABLE insertR #-}
    #else
    {-# INLINE insertR #-}
    #endif

    -- | \(O(\log n)\). Delete an element from a set.

    -- See Note: Type of local 'go' function
    delete :: Ord a => a -> Set a -> Set a
    delete :: forall a. Ord a => a -> Set a -> Set a
    delete = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    go
      where
        go :: Ord a => a -> Set a -> Set a
        go :: forall a. Ord a => a -> Set a -> Set a
    go !a
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
        go a
    x t :: Set a
    t@(Bin Size
    _ a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
            Ordering
    LT | Set a
    l' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    l' Set a
    r
               where !l' :: Set a
    l' = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    go a
    x Set a
    l
            Ordering
    GT | Set a
    r' Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r -> Set a
    t
               | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y Set a
    l Set a
    r'
               where !r' :: Set a
    r' = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    go a
    x Set a
    r
            Ordering
    EQ -> Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    glue Set a
    l Set a
    r
    #if __GLASGOW_HASKELL__
    {-# INLINABLE delete #-}
    #else
    {-# INLINE delete #-}
    #endif

    -- | \(O(\log n)\) @('alterF' f x s)@ can delete or insert @x@ in @s@ depending on
    -- whether an equal element is found in @s@.
    --
    -- In short:
    --
    -- @
    -- 'member' x \<$\> 'alterF' f x s = f ('member' x s)
    -- @
    --
    -- Note that unlike 'insert', 'alterF' will /not/ replace an element equal to
    -- the given value.
    --
    -- Note: 'alterF' is a variant of the @at@ combinator from "Control.Lens.At".
    --
    -- @since 0.6.3.1
    alterF :: (Ord a, Functor f) => (Bool -> f Bool) -> a -> Set a -> f (Set a)
    alterF :: forall a (f :: * -> *).
    (Ord a, Functor f) =>
    (Bool -> f Bool) -> a -> Set a -> f (Set a)
    alterF Bool -> f Bool
    f a
    k Set a
    s = (Bool -> Set a) -> f Bool -> f (Set a)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Bool -> Set a
    choose (Bool -> f Bool
    f Bool
    member_)
      where
        (Bool
    member_, Set a
    inserted, Set a
    deleted) = case a -> Set a -> AlteredSet a
    forall a. Ord a => a -> Set a -> AlteredSet a
    alteredSet a
    k Set a
    s of
            Deleted Set a
    d           -> (Bool
    True , Set a
    s, Set a
    d)
            Inserted Set a
    i          -> (Bool
    False, Set a
    i, Set a
    s)

        choose :: Bool -> Set a
    choose Bool
    True  = Set a
    inserted
        choose Bool
    False = Set a
    deleted
    #ifndef __GLASGOW_HASKELL__
    {-# INLINE alterF #-}
    #else
    {-# INLINABLE [2] alterF #-}

    {-# RULES
    "alterF/Const" forall k (f :: Bool -> Const a Bool) . alterF f k = \s -> Const . getConst . f $ member k s
     #-}
    #endif

    {-# SPECIALIZE alterF :: Ord a => (Bool -> Identity Bool) -> a -> Set a -> Identity (Set a) #-}

    data AlteredSet a
          -- | The needle is present in the original set.
          -- We return the set where the needle is deleted.
        = Deleted !(Set a)

          -- | The needle is not present in the original set.
          -- We return the set with the needle inserted.
        | Inserted !(Set a)

    alteredSet :: Ord a => a -> Set a -> AlteredSet a
    alteredSet :: forall a. Ord a => a -> Set a -> AlteredSet a
    alteredSet a
    x0 Set a
    s0 = a -> Set a -> AlteredSet a
    forall a. Ord a => a -> Set a -> AlteredSet a
    go a
    x0 Set a
    s0
      where
        go :: Ord a => a -> Set a -> AlteredSet a
        go :: forall a. Ord a => a -> Set a -> AlteredSet a
    go a
    x Set a
    Tip           = Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Inserted (a -> Set a
    forall a. a -> Set a
    singleton a
    x)
        go a
    x (Bin Size
    _ a
    y Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
            Ordering
    LT -> case a -> Set a -> AlteredSet a
    forall a. Ord a => a -> Set a -> AlteredSet a
    go a
    x Set a
    l of
                Deleted Set a
    d           -> Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Deleted (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    d Set a
    r)
                Inserted Set a
    i          -> Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Inserted (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y Set a
    i Set a
    r)
            Ordering
    GT -> case a -> Set a -> AlteredSet a
    forall a. Ord a => a -> Set a -> AlteredSet a
    go a
    x Set a
    r of
                Deleted Set a
    d           -> Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Deleted (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y Set a
    l Set a
    d)
                Inserted Set a
    i          -> Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Inserted (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    l Set a
    i)
            Ordering
    EQ -> Set a -> AlteredSet a
    forall a. Set a -> AlteredSet a
    Deleted (Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    glue Set a
    l Set a
    r)
    #if __GLASGOW_HASKELL__
    {-# INLINABLE alteredSet #-}
    #else
    {-# INLINE alteredSet #-}
    #endif

    {--------------------------------------------------------------------
      Subset
    --------------------------------------------------------------------}
    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
    -- @(s1 \`isProperSubsetOf\` s2)@ indicates whether @s1@ is a
    -- proper subset of @s2@.
    --
    -- @
    -- s1 \`isProperSubsetOf\` s2 = s1 ``isSubsetOf`` s2 && s1 /= s2
    -- @
    isProperSubsetOf :: Ord a => Set a -> Set a -> Bool
    isProperSubsetOf :: forall a. Ord a => Set a -> Set a -> Bool
    isProperSubsetOf Set a
    s1 Set a
    s2
        = Set a -> Size
    forall a. Set a -> Size
    size Set a
    s1 Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Set a -> Size
    forall a. Set a -> Size
    size Set a
    s2 Bool -> Bool -> Bool
    && Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOfX Set a
    s1 Set a
    s2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE isProperSubsetOf #-}
    #endif

    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
    -- @(s1 \`isSubsetOf\` s2)@ indicates whether @s1@ is a subset of @s2@.
    --
    -- @
    -- s1 \`isSubsetOf\` s2 = all (``member`` s2) s1
    -- s1 \`isSubsetOf\` s2 = null (s1 ``difference`` s2)
    -- s1 \`isSubsetOf\` s2 = s1 ``union`` s2 == s2
    -- s1 \`isSubsetOf\` s2 = s1 ``intersection`` s2 == s1
    -- @
    isSubsetOf :: Ord a => Set a -> Set a -> Bool
    isSubsetOf :: forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOf Set a
    t1 Set a
    t2
      = Set a -> Size
    forall a. Set a -> Size
    size Set a
    t1 Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Size
    forall a. Set a -> Size
    size Set a
    t2 Bool -> Bool -> Bool
    && Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOfX Set a
    t1 Set a
    t2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE isSubsetOf #-}
    #endif

    -- Test whether a set is a subset of another without the *initial*
    -- size test.
    --
    -- This function is structured very much like `difference`, `union`,
    -- and `intersection`. Whereas the bounds proofs for those in Blelloch
    -- et al needed to account for both "split work" and "merge work", we
    -- only have to worry about split work here, which is the same as in
    -- those functions.
    isSubsetOfX :: Ord a => Set a -> Set a -> Bool
    isSubsetOfX :: forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOfX Set a
    Tip Set a
    _ = Bool
    True
    isSubsetOfX Set a
    _ Set a
    Tip = Bool
    False
    -- Skip the final split when we hit a singleton.
    isSubsetOfX (Bin Size
    1 a
    x Set a
    _ Set a
    _) Set a
    t = a -> Set a -> Bool
    forall a. Ord a => a -> Set a -> Bool
    member a
    x Set a
    t
    isSubsetOfX (Bin Size
    _ a
    x Set a
    l Set a
    r) Set a
    t
      = Bool
    found Bool -> Bool -> Bool
    &&
        -- Cheap size checks can sometimes save expensive recursive calls when the
        -- result will be False. Suppose we check whether [1..10] (with root 4) is
        -- a subset of [0..9]. After the first split, we have to check if [1..3] is
        -- a subset of [0..3] and if [5..10] is a subset of [5..9]. But we can bail
        -- immediately because size [5..10] > size [5..9].
        --
        -- Why not just call `isSubsetOf` on each side to do the size checks?
        -- Because that could make a recursive call on the left even though the
        -- size check would fail on the right. In principle, we could take this to
        -- extremes by maintaining a queue of pairs of sets to be checked, working
        -- through the tree level-wise. But that would impose higher administrative
        -- costs without obvious benefits. It might be worth considering if we find
        -- a way to use it to tighten the bounds in some useful/comprehensible way.
        Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Size
    forall a. Set a -> Size
    size Set a
    lt Bool -> Bool -> Bool
    && Set a -> Size
    forall a. Set a -> Size
    size Set a
    r Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Size
    forall a. Set a -> Size
    size Set a
    gt Bool -> Bool -> Bool
    &&
        Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOfX Set a
    l Set a
    lt Bool -> Bool -> Bool
    && Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    isSubsetOfX Set a
    r Set a
    gt
      where
        (Set a
    lt,Bool
    found,Set a
    gt) = a -> Set a -> (Set a, Bool, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    x Set a
    t
    #if __GLASGOW_HASKELL__
    {-# INLINABLE isSubsetOfX #-}
    #endif

    {--------------------------------------------------------------------
      Disjoint
    --------------------------------------------------------------------}
    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Check whether two sets are disjoint
    -- (i.e., their intersection is empty).
    --
    -- > disjoint (fromList [2,4,6])   (fromList [1,3])     == True
    -- > disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
    -- > disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
    -- > disjoint (fromList [])        (fromList [])        == True
    --
    -- @
    -- xs ``disjoint`` ys = null (xs ``intersection`` ys)
    -- @
    --
    -- @since 0.5.11

    disjoint :: Ord a => Set a -> Set a -> Bool
    disjoint :: forall a. Ord a => Set a -> Set a -> Bool
    disjoint Set a
    Tip Set a
    _ = Bool
    True
    disjoint Set a
    _ Set a
    Tip = Bool
    True
    -- Avoid a split for the singleton case.
    disjoint (Bin Size
    1 a
    x Set a
    _ Set a
    _) Set a
    t = a
    x a -> Set a -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `notMember` Set a
    t
    disjoint (Bin Size
    _ a
    x Set a
    l Set a
    r) Set a
    t
      -- Analogous implementation to `subsetOfX`
      = Bool -> Bool
    not Bool
    found Bool -> Bool -> Bool
    && Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    disjoint Set a
    l Set a
    lt Bool -> Bool -> Bool
    && Set a -> Set a -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    disjoint Set a
    r Set a
    gt
      where
        (Set a
    lt,Bool
    found,Set a
    gt) = a -> Set a -> (Set a, Bool, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    x Set a
    t

    {--------------------------------------------------------------------
      Minimal, Maximal
    --------------------------------------------------------------------}

    -- We perform call-pattern specialization manually on lookupMin
    -- and lookupMax. Otherwise, GHC doesn't seem to do it, which is
    -- unfortunate if, for example, someone uses findMin or findMax.

    lookupMinSure :: a -> Set a -> a
    lookupMinSure :: forall a. a -> Set a -> a
    lookupMinSure a
    x Set a
    Tip = a
    x
    lookupMinSure a
    _ (Bin Size
    _ a
    x Set a
    l Set a
    _) = a -> Set a -> a
    forall a. a -> Set a -> a
    lookupMinSure a
    x Set a
    l

    -- | \(O(\log n)\). The minimal element of a set.
    --
    -- @since 0.5.9

    lookupMin :: Set a -> Maybe a
    lookupMin :: forall a. Set a -> Maybe a
    lookupMin Set a
    Tip = Maybe a
    forall a. Maybe a
    Nothing
    lookupMin (Bin Size
    _ a
    x Set a
    l Set a
    _) = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a -> Set a -> a
    forall a. a -> Set a -> a
    lookupMinSure a
    x Set a
    l

    -- | \(O(\log n)\). The minimal element of a set.
    findMin :: Set a -> a
    findMin :: forall a. Set a -> a
    findMin Set a
    t
      | Just a
    r <- Set a -> Maybe a
    forall a. Set a -> Maybe a
    lookupMin Set a
    t = a
    r
      | Bool
    otherwise = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.findMin: empty set has no minimal element"

    lookupMaxSure :: a -> Set a -> a
    lookupMaxSure :: forall a. a -> Set a -> a
    lookupMaxSure a
    x Set a
    Tip = a
    x
    lookupMaxSure a
    _ (Bin Size
    _ a
    x Set a
    _ Set a
    r) = a -> Set a -> a
    forall a. a -> Set a -> a
    lookupMaxSure a
    x Set a
    r

    -- | \(O(\log n)\). The maximal element of a set.
    --
    -- @since 0.5.9

    lookupMax :: Set a -> Maybe a
    lookupMax :: forall a. Set a -> Maybe a
    lookupMax Set a
    Tip = Maybe a
    forall a. Maybe a
    Nothing
    lookupMax (Bin Size
    _ a
    x Set a
    _ Set a
    r) = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $! a -> Set a -> a
    forall a. a -> Set a -> a
    lookupMaxSure a
    x Set a
    r

    -- | \(O(\log n)\). The maximal element of a set.
    findMax :: Set a -> a
    findMax :: forall a. Set a -> a
    findMax Set a
    t
      | Just a
    r <- Set a -> Maybe a
    forall a. Set a -> Maybe a
    lookupMax Set a
    t = a
    r
      | Bool
    otherwise = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.findMax: empty set has no maximal element"

    -- | \(O(\log n)\). Delete the minimal element. Returns an empty set if the set is empty.
    deleteMin :: Set a -> Set a
    deleteMin :: forall a. Set a -> Set a
    deleteMin (Bin Size
    _ a
    _ Set a
    Tip Set a
    r) = Set a
    r
    deleteMin (Bin Size
    _ a
    x Set a
    l Set a
    r)   = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    x (Set a -> Set a
    forall a. Set a -> Set a
    deleteMin Set a
    l) Set a
    r
    deleteMin Set a
    Tip             = Set a
    forall a. Set a
    Tip

    -- | \(O(\log n)\). Delete the maximal element. Returns an empty set if the set is empty.
    deleteMax :: Set a -> Set a
    deleteMax :: forall a. Set a -> Set a
    deleteMax (Bin Size
    _ a
    _ Set a
    l Set a
    Tip) = Set a
    l
    deleteMax (Bin Size
    _ a
    x Set a
    l Set a
    r)   = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    x Set a
    l (Set a -> Set a
    forall a. Set a -> Set a
    deleteMax Set a
    r)
    deleteMax Set a
    Tip             = Set a
    forall a. Set a
    Tip

    {--------------------------------------------------------------------
      Union.
    --------------------------------------------------------------------}
    -- | The union of the sets in a Foldable structure : (@'unions' == 'foldl' 'union' 'empty'@).
    unions :: (Foldable f, Ord a) => f (Set a) -> Set a
    unions :: forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
    unions = (Set a -> Set a -> Set a) -> Set a -> f (Set a) -> Set a
    forall b a. (b -> a -> b) -> b -> f a -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    union Set a
    forall a. Set a
    empty
    #if __GLASGOW_HASKELL__
    {-# INLINABLE unions #-}
    #endif

    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). The union of two sets, preferring the first set when
    -- equal elements are encountered.
    union :: Ord a => Set a -> Set a -> Set a
    union :: forall a. Ord a => Set a -> Set a -> Set a
    union Set a
    t1 Set a
    Tip  = Set a
    t1
    union Set a
    t1 (Bin Size
    1 a
    x Set a
    _ Set a
    _) = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    insertR a
    x Set a
    t1
    union (Bin Size
    1 a
    x Set a
    _ Set a
    _) Set a
    t2 = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    insert a
    x Set a
    t2
    union Set a
    Tip Set a
    t2  = Set a
    t2
    union t1 :: Set a
    t1@(Bin Size
    _ a
    x Set a
    l1 Set a
    r1) Set a
    t2 = case a -> Set a -> StrictPair (Set a) (Set a)
    forall a. Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS a
    x Set a
    t2 of
      (Set a
    l2 :*: Set a
    r2)
        | Set a
    l1l2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l1 Bool -> Bool -> Bool
    && Set a
    r1r2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r1 -> Set a
    t1
        | Bool
    otherwise -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l1l2 Set a
    r1r2
        where !l1l2 :: Set a
    l1l2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    union Set a
    l1 Set a
    l2
              !r1r2 :: Set a
    r1r2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    union Set a
    r1 Set a
    r2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE union #-}
    #endif

    {--------------------------------------------------------------------
      Difference
    --------------------------------------------------------------------}
    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Difference of two sets.
    --
    -- Return elements of the first set not existing in the second set.
    --
    -- > difference (fromList [5, 3]) (fromList [5, 7]) == singleton 3
    difference :: Ord a => Set a -> Set a -> Set a
    difference :: forall a. Ord a => Set a -> Set a -> Set a
    difference Set a
    Tip Set a
    _   = Set a
    forall a. Set a
    Tip
    difference Set a
    t1 Set a
    Tip  = Set a
    t1
    difference Set a
    t1 (Bin Size
    _ a
    x Set a
    l2 Set a
    r2) = case a -> Set a -> (Set a, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Set a)
    split a
    x Set a
    t1 of
       (Set a
    l1, Set a
    r1)
         | Set a -> Size
    forall a. Set a -> Size
    size Set a
    l1l2 Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    r1r2 Size -> Size -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> Size
    forall a. Set a -> Size
    size Set a
    t1 -> Set a
    t1
         | Bool
    otherwise -> Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l1l2 Set a
    r1r2
         where !l1l2 :: Set a
    l1l2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    difference Set a
    l1 Set a
    l2
               !r1r2 :: Set a
    r1r2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    difference Set a
    r1 Set a
    r2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE difference #-}
    #endif

    {--------------------------------------------------------------------
      Intersection
    --------------------------------------------------------------------}
    -- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). The intersection of two sets.
    -- Elements of the result come from the first set, so for example
    --
    -- > import qualified Data.Set as S
    -- > data AB = A | B deriving Show
    -- > instance Ord AB where compare _ _ = EQ
    -- > instance Eq AB where _ == _ = True
    -- > main = print (S.singleton A `S.intersection` S.singleton B,
    -- >               S.singleton B `S.intersection` S.singleton A)
    --
    -- prints @(fromList [A],fromList [B])@.
    intersection :: Ord a => Set a -> Set a -> Set a
    intersection :: forall a. Ord a => Set a -> Set a -> Set a
    intersection Set a
    Tip Set a
    _ = Set a
    forall a. Set a
    Tip
    intersection Set a
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
    intersection t1 :: Set a
    t1@(Bin Size
    _ a
    x Set a
    l1 Set a
    r1) Set a
    t2
      | Bool
    b = if Set a
    l1l2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l1 Bool -> Bool -> Bool
    && Set a
    r1r2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r1
            then Set a
    t1
            else a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l1l2 Set a
    r1r2
      | Bool
    otherwise = Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l1l2 Set a
    r1r2
      where
        !(Set a
    l2, Bool
    b, Set a
    r2) = a -> Set a -> (Set a, Bool, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    x Set a
    t2
        !l1l2 :: Set a
    l1l2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    intersection Set a
    l1 Set a
    l2
        !r1r2 :: Set a
    r1r2 = Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    intersection Set a
    r1 Set a
    r2
    #if __GLASGOW_HASKELL__
    {-# INLINABLE intersection #-}
    #endif

    -- | The intersection of a series of sets. Intersections are performed left-to-right.
    intersections :: Ord a => NonEmpty (Set a) -> Set a
    intersections :: forall a. Ord a => NonEmpty (Set a) -> Set a
    intersections (Set a
    s0 :| [Set a]
    ss) = (Set a -> (Set a -> Set a) -> Set a -> Set a)
    -> (Set a -> Set a) -> [Set a] -> Set a -> Set a
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    List.foldr Set a -> (Set a -> Set a) -> Set a -> Set a
    forall {a} {a}.
    Ord a =>
    Set a -> (Set a -> Set a) -> Set a -> Set a
    go Set a -> Set a
    forall a. a -> a
    id [Set a]
    ss Set a
    s0
        where
          go :: Set a -> (Set a -> Set a) -> Set a -> Set a
    go Set a
    s Set a -> Set a
    r Set a
    acc
              | Set a -> Bool
    forall a. Set a -> Bool
    null Set a
    acc = Set a
    forall a. Set a
    empty
              | Bool
    otherwise = Set a -> Set a
    r (Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    intersection Set a
    acc Set a
    s)

    -- | Sets form a 'Semigroup' under 'intersection'.
    newtype Intersection a = Intersection { forall a. Intersection a -> Set a
    getIntersection :: Set a }
        deriving (Size -> Intersection a -> ShowS
    [Intersection a] -> ShowS
    Intersection a -> [Char]
    (Size -> Intersection a -> ShowS)
    -> (Intersection a -> [Char])
    -> ([Intersection a] -> ShowS)
    -> Show (Intersection a)
    forall a. Show a => Size -> Intersection a -> ShowS
    forall a. Show a => [Intersection a] -> ShowS
    forall a. Show a => Intersection a -> [Char]
    forall a.
    (Size -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Size -> Intersection a -> ShowS
    showsPrec :: Size -> Intersection a -> ShowS
    $cshow :: forall a. Show a => Intersection a -> [Char]
    show :: Intersection a -> [Char]
    $cshowList :: forall a. Show a => [Intersection a] -> ShowS
    showList :: [Intersection a] -> ShowS
    Show, Intersection a -> Intersection a -> Bool
    (Intersection a -> Intersection a -> Bool)
    -> (Intersection a -> Intersection a -> Bool)
    -> Eq (Intersection a)
    forall a. Eq a => Intersection a -> Intersection a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Intersection a -> Intersection a -> Bool
    == :: Intersection a -> Intersection a -> Bool
    $c/= :: forall a. Eq a => Intersection a -> Intersection a -> Bool
    /= :: Intersection a -> Intersection a -> Bool
    Eq, Eq (Intersection a)
    Eq (Intersection a) =>
    (Intersection a -> Intersection a -> Ordering)
    -> (Intersection a -> Intersection a -> Bool)
    -> (Intersection a -> Intersection a -> Bool)
    -> (Intersection a -> Intersection a -> Bool)
    -> (Intersection a -> Intersection a -> Bool)
    -> (Intersection a -> Intersection a -> Intersection a)
    -> (Intersection a -> Intersection a -> Intersection a)
    -> Ord (Intersection a)
    Intersection a -> Intersection a -> Bool
    Intersection a -> Intersection a -> Ordering
    Intersection a -> Intersection a -> Intersection a
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall a. Ord a => Eq (Intersection a)
    forall a. Ord a => Intersection a -> Intersection a -> Bool
    forall a. Ord a => Intersection a -> Intersection a -> Ordering
    forall a.
    Ord a =>
    Intersection a -> Intersection a -> Intersection a
    $ccompare :: forall a. Ord a => Intersection a -> Intersection a -> Ordering
    compare :: Intersection a -> Intersection a -> Ordering
    $c< :: forall a. Ord a => Intersection a -> Intersection a -> Bool
    < :: Intersection a -> Intersection a -> Bool
    $c<= :: forall a. Ord a => Intersection a -> Intersection a -> Bool
    <= :: Intersection a -> Intersection a -> Bool
    $c> :: forall a. Ord a => Intersection a -> Intersection a -> Bool
    > :: Intersection a -> Intersection a -> Bool
    $c>= :: forall a. Ord a => Intersection a -> Intersection a -> Bool
    >= :: Intersection a -> Intersection a -> Bool
    $cmax :: forall a.
    Ord a =>
    Intersection a -> Intersection a -> Intersection a
    max :: Intersection a -> Intersection a -> Intersection a
    $cmin :: forall a.
    Ord a =>
    Intersection a -> Intersection a -> Intersection a
    min :: Intersection a -> Intersection a -> Intersection a
    Ord)

    instance (Ord a) => Semigroup (Intersection a) where
        (Intersection Set a
    a) <> :: Intersection a -> Intersection a -> Intersection a
    <> (Intersection Set a
    b) = Set a -> Intersection a
    forall a. Set a -> Intersection a
    Intersection (Set a -> Intersection a) -> Set a -> Intersection a
    forall a b. (a -> b) -> a -> b
    $ Set a -> Set a -> Set a
    forall a. Ord a => Set a -> Set a -> Set a
    intersection Set a
    a Set a
    b
        stimes :: forall b. Integral b => b -> Intersection a -> Intersection a
    stimes = b -> Intersection a -> Intersection a
    forall b a. Integral b => b -> a -> a
    stimesIdempotent

    {--------------------------------------------------------------------
      Filter and partition
    --------------------------------------------------------------------}
    -- | \(O(n)\). Filter all elements that satisfy the predicate.
    filter :: (a -> Bool) -> Set a -> Set a
    filter :: forall a. (a -> Bool) -> Set a -> Set a
    filter a -> Bool
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
    filter a -> Bool
    p t :: Set a
    t@(Bin Size
    _ a
    x Set a
    l Set a
    r)
        | a -> Bool
    p a
    x = if Set a
    l Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l' Bool -> Bool -> Bool
    && Set a
    r Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r'
                then Set a
    t
                else a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l' Set a
    r'
        | Bool
    otherwise = Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l' Set a
    r'
        where
          !l' :: Set a
    l' = (a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    filter a -> Bool
    p Set a
    l
          !r' :: Set a
    r' = (a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    filter a -> Bool
    p Set a
    r

    -- | \(O(n)\). Partition the set into two sets, one with all elements that satisfy
    -- the predicate and one with all elements that don't satisfy the predicate.
    -- See also 'split'.
    partition :: (a -> Bool) -> Set a -> (Set a,Set a)
    partition :: forall a. (a -> Bool) -> Set a -> (Set a, Set a)
    partition a -> Bool
    p0 Set a
    t0 = StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair (StrictPair (Set a) (Set a) -> (Set a, Set a))
    -> StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. (a -> b) -> a -> b
    $ (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    forall {a}. (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p0 Set a
    t0
      where
        go :: (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    _ Set a
    Tip = (Set a
    forall a. Set a
    Tip Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    forall a. Set a
    Tip)
        go a -> Bool
    p t :: Set a
    t@(Bin Size
    _ a
    x Set a
    l Set a
    r) = case ((a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p Set a
    l, (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p Set a
    r) of
          ((Set a
    l1 :*: Set a
    l2), (Set a
    r1 :*: Set a
    r2))
            | a -> Bool
    p a
    x       -> (if Set a
    l1 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l Bool -> Bool -> Bool
    && Set a
    r1 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r
                            then Set a
    t
                            else a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l1 Set a
    r1) Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l2 Set a
    r2
            | Bool
    otherwise -> Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l1 Set a
    r1 Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*:
                           (if Set a
    l2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    l Bool -> Bool -> Bool
    && Set a
    r2 Set a -> Set a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` Set a
    r
                            then Set a
    t
                            else a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l2 Set a
    r2)

    {----------------------------------------------------------------------
      Map
    ----------------------------------------------------------------------}

    -- | \(O(n \log n)\).
    -- @'map' f s@ is the set obtained by applying @f@ to each element of @s@.
    --
    -- It's worth noting that the size of the result may be smaller if,
    -- for some @(x,y)@, @x \/= y && f x == f y@

    map :: Ord b => (a->b) -> Set a -> Set b
    map :: forall b a. Ord b => (a -> b) -> Set a -> Set b
    map a -> b
    f = [b] -> Set b
    forall a. Ord a => [a] -> Set a
    fromList ([b] -> Set b) -> (Set a -> [b]) -> Set a -> Set b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b) -> [a] -> [b]
    forall a b. (a -> b) -> [a] -> [b]
    List.map a -> b
    f ([a] -> [b]) -> (Set a -> [a]) -> Set a -> [b]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Set a -> [a]
    forall a. Set a -> [a]
    toList
    #if __GLASGOW_HASKELL__
    {-# INLINABLE map #-}
    #endif

    -- | \(O(n)\). The
    --
    -- @'mapMonotonic' f s == 'map' f s@, but works only when @f@ is strictly increasing.
    -- /The precondition is not checked./
    -- Semi-formally, we have:
    --
    -- > and [x < y ==> f x < f y | x <- ls, y <- ls]
    -- >                     ==> mapMonotonic f s == map f s
    -- >     where ls = toList s

    mapMonotonic :: (a->b) -> Set a -> Set b
    mapMonotonic :: forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic a -> b
    _ Set a
    Tip = Set b
    forall a. Set a
    Tip
    mapMonotonic a -> b
    f (Bin Size
    sz a
    x Set a
    l Set a
    r) = Size -> b -> Set b -> Set b -> Set b
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    sz (a -> b
    f a
    x) ((a -> b) -> Set a -> Set b
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic a -> b
    f Set a
    l) ((a -> b) -> Set a -> Set b
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic a -> b
    f Set a
    r)

    {--------------------------------------------------------------------
      Fold
    --------------------------------------------------------------------}
    -- | \(O(n)\). Fold the elements in the set using the given right-associative
    -- binary operator. This function is an equivalent of 'foldr' and is present
    -- for compatibility only.
    --
    -- /Please note that fold will be deprecated in the future and removed./
    fold :: (a -> b -> b) -> b -> Set a -> b
    fold :: forall a b. (a -> b -> b) -> b -> Set a -> b
    fold = (a -> b -> b) -> b -> Set a -> b
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr
    {-# INLINE fold #-}

    -- | \(O(n)\). Fold the elements in the set using the given right-associative
    -- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'toAscList'@.
    --
    -- For example,
    --
    -- > toAscList set = foldr (:) [] set
    foldr :: (a -> b -> b) -> b -> Set a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr a -> b -> b
    f b
    z = b -> Set a -> b
    go b
    z
      where
        go :: b -> Set a -> b
    go b
    z' Set a
    Tip           = b
    z'
        go b
    z' (Bin Size
    _ a
    x Set a
    l Set a
    r) = b -> Set a -> b
    go (a -> b -> b
    f a
    x (b -> Set a -> b
    go b
    z' Set a
    r)) Set 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 -> Set a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr' a -> b -> b
    f b
    z = b -> Set a -> b
    go b
    z
      where
        go :: b -> Set a -> b
    go !b
    z' Set a
    Tip           = b
    z'
        go b
    z' (Bin Size
    _ a
    x Set a
    l Set a
    r) = b -> Set a -> b
    go (a -> b -> b
    f a
    x (b -> b) -> b -> b
    forall a b. (a -> b) -> a -> b
    $! b -> Set a -> b
    go b
    z' Set a
    r) Set a
    l
    {-# INLINE foldr' #-}

    -- | \(O(n)\). Fold the elements in the set using the given left-associative
    -- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'toAscList'@.
    --
    -- For example,
    --
    -- > toDescList set = foldl (flip (:)) [] set
    foldl :: (a -> b -> a) -> a -> Set b -> a
    foldl :: forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl a -> b -> a
    f a
    z = a -> Set b -> a
    go a
    z
      where
        go :: a -> Set b -> a
    go a
    z' Set b
    Tip           = a
    z'
        go a
    z' (Bin Size
    _ b
    x Set b
    l Set b
    r) = a -> Set b -> a
    go (a -> b -> a
    f (a -> Set b -> a
    go a
    z' Set b
    l) b
    x) Set 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 -> Set b -> a
    foldl' :: forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl' a -> b -> a
    f a
    z = a -> Set b -> a
    go a
    z
      where
        go :: a -> Set b -> a
    go !a
    z' Set b
    Tip           = a
    z'
        go a
    z' (Bin Size
    _ b
    x Set b
    l Set b
    r) =
          let !z'' :: a
    z'' = a -> Set b -> a
    go a
    z' Set b
    l
          in a -> Set b -> a
    go (a -> b -> a
    f a
    z'' b
    x) Set b
    r
    {-# INLINE foldl' #-}

    {--------------------------------------------------------------------
      List variations
    --------------------------------------------------------------------}
    -- | \(O(n)\). An alias of 'toAscList'. The elements of a set in ascending order.
    -- Subject to list fusion.
    elems :: Set a -> [a]
    elems :: forall a. Set a -> [a]
    elems = Set a -> [a]
    forall a. Set a -> [a]
    toAscList

    {--------------------------------------------------------------------
      Lists
    --------------------------------------------------------------------}

    #ifdef __GLASGOW_HASKELL__
    -- | @since 0.5.6.2
    instance (Ord a) => GHCExts.IsList (Set a) where
      type Item (Set a) = a
      fromList :: [Item (Set a)] -> Set a
    fromList = [a] -> Set a
    [Item (Set a)] -> Set a
    forall a. Ord a => [a] -> Set a
    fromList
      toList :: Set a -> [Item (Set a)]
    toList   = Set a -> [a]
    Set a -> [Item (Set a)]
    forall a. Set a -> [a]
    toList
    #endif

    -- | \(O(n)\). Convert the set to a list of elements. Subject to list fusion.
    toList :: Set a -> [a]
    toList :: forall a. Set a -> [a]
    toList = Set a -> [a]
    forall a. Set a -> [a]
    toAscList

    -- | \(O(n)\). Convert the set to an ascending list of elements. Subject to list fusion.
    toAscList :: Set a -> [a]
    toAscList :: forall a. Set a -> [a]
    toAscList = (a -> [a] -> [a]) -> [a] -> Set a -> [a]
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr (:) []

    -- | \(O(n)\). Convert the set to a descending list of elements. Subject to list
    -- fusion.
    toDescList :: Set a -> [a]
    toDescList :: forall a. Set a -> [a]
    toDescList = ([a] -> a -> [a]) -> [a] -> Set a -> [a]
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl ((a -> [a] -> [a]) -> [a] -> a -> [a]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (:)) []

    -- List fusion for the list generating functions.
    #if __GLASGOW_HASKELL__
    -- The foldrFB and foldlFB are foldr and foldl equivalents, used for list fusion.
    -- They are important to convert unfused to{Asc,Desc}List back, see mapFB in prelude.
    foldrFB :: (a -> b -> b) -> b -> Set a -> b
    foldrFB :: forall a b. (a -> b -> b) -> b -> Set a -> b
    foldrFB = (a -> b -> b) -> b -> Set a -> b
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr
    {-# INLINE[0] foldrFB #-}
    foldlFB :: (a -> b -> a) -> a -> Set b -> a
    foldlFB :: forall b a. (b -> a -> b) -> b -> Set a -> b
    foldlFB = (a -> b -> a) -> a -> Set b -> a
    forall b a. (b -> a -> b) -> b -> Set a -> b
    foldl
    {-# INLINE[0] foldlFB #-}

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

    -- The fusion is enabled up to phase 2 included. If it does not succeed,
    -- convert in phase 1 the expanded to{Asc,Desc}List calls back to
    -- 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 to{Asc,Desc}List -- it was forbidden to inline it
    -- before phase 0, otherwise the fusion rules would not fire at all.
    {-# NOINLINE[0] toAscList #-}
    {-# NOINLINE[0] toDescList #-}
    {-# RULES "Set.toAscList" [~1] forall s . toAscList s = build (\c n -> foldrFB c n s) #-}
    {-# RULES "Set.toAscListBack" [1] foldrFB (:) [] = toAscList #-}
    {-# RULES "Set.toDescList" [~1] forall s . toDescList s = build (\c n -> foldlFB (\xs x -> c x xs) n s) #-}
    {-# RULES "Set.toDescListBack" [1] foldlFB (\xs x -> x : xs) [] = toDescList #-}
    #endif

    -- | \(O(n \log n)\). Create a set from a list of elements.
    --
    -- If the elements are ordered, a linear-time implementation is used,
    -- with the performance equal to 'fromDistinctAscList'.

    -- For some reason, when 'singleton' is used in fromList or in
    -- create, it is not inlined, so we inline it manually.
    fromList :: Ord a => [a] -> Set a
    fromList :: forall a. Ord a => [a] -> Set a
    fromList [] = Set a
    forall a. Set a
    Tip
    fromList [a
    x] = Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
    fromList (a
    x0 : [a]
    xs0) | a -> [a] -> Bool
    forall {a}. Ord a => a -> [a] -> Bool
    not_ordered a
    x0 [a]
    xs0 = Set a -> [a] -> Set a
    forall {t :: * -> *} {a}.
    (Foldable t, Ord a) =>
    Set a -> t a -> Set a
    fromList' (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x0 Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) [a]
    xs0
                        | Bool
    otherwise = Size -> Set a -> [a] -> Set a
    forall {a} {t}.
    (Ord a, Num t, Bits t) =>
    t -> Set a -> [a] -> Set a
    go (Size
    1::Int) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x0 Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) [a]
    xs0
      where
        not_ordered :: a -> [a] -> Bool
    not_ordered a
    _ [] = Bool
    False
        not_ordered a
    x (a
    y : [a]
    _) = a
    x a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    y
        {-# INLINE not_ordered #-}

        fromList' :: Set a -> t a -> Set a
    fromList' Set a
    t0 t a
    xs = (Set a -> a -> Set a) -> Set a -> t a -> Set a
    forall b a. (b -> a -> b) -> b -> t a -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    Foldable.foldl' Set a -> a -> Set a
    forall {a}. Ord a => Set a -> a -> Set a
    ins Set a
    t0 t a
    xs
          where ins :: Set a -> a -> Set a
    ins Set a
    t a
    x = a -> Set a -> Set a
    forall a. Ord a => a -> Set a -> Set a
    insert a
    x Set a
    t

        go :: t -> Set a -> [a] -> Set a
    go !t
    _ Set a
    t [] = Set a
    t
        go t
    _ Set a
    t [a
    x] = a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMax a
    x Set a
    t
        go t
    s Set a
    l xs :: [a]
    xs@(a
    x : [a]
    xss) | a -> [a] -> Bool
    forall {a}. Ord a => a -> [a] -> Bool
    not_ordered a
    x [a]
    xss = Set a -> [a] -> Set a
    forall {t :: * -> *} {a}.
    (Foldable t, Ord a) =>
    Set a -> t a -> Set a
    fromList' Set a
    l [a]
    xs
                            | Bool
    otherwise = case t -> [a] -> (Set a, [a], [a])
    forall {t} {a}.
    (Num t, Ord a, Bits t) =>
    t -> [a] -> (Set a, [a], [a])
    create t
    s [a]
    xss of
                                (Set a
    r, [a]
    ys, []) -> t -> Set a -> [a] -> Set a
    go (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftL` Size
    1) (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    r) [a]
    ys
                                (Set a
    r, [a]
    _,  [a]
    ys) -> Set a -> [a] -> Set a
    forall {t :: * -> *} {a}.
    (Foldable t, Ord a) =>
    Set a -> t a -> Set a
    fromList' (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    r) [a]
    ys

        -- The create is returning a triple (tree, xs, ys). Both xs and ys
        -- represent not yet processed elements and only one of them can be nonempty.
        -- If ys is nonempty, the keys in ys are not ordered with respect to tree
        -- and must be inserted using fromList'. Otherwise the keys have been
        -- ordered so far.
        create :: t -> [a] -> (Set a, [a], [a])
    create !t
    _ [] = (Set a
    forall a. Set a
    Tip, [], [])
        create t
    s xs :: [a]
    xs@(a
    x : [a]
    xss)
          | t
    s t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    1 = if a -> [a] -> Bool
    forall {a}. Ord a => a -> [a] -> Bool
    not_ordered a
    x [a]
    xss then (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip, [], [a]
    xss)
                                          else (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip, [a]
    xss, [])
          | Bool
    otherwise = case t -> [a] -> (Set a, [a], [a])
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    xs of
                          res :: (Set a, [a], [a])
    res@(Set a
    _, [], [a]
    _) -> (Set a, [a], [a])
    res
                          (Set a
    l, [a
    y], [a]
    zs) -> (a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMax a
    y Set a
    l, [], [a]
    zs)
                          (Set a
    l, ys :: [a]
    ys@(a
    y:[a]
    yss), [a]
    _) | a -> [a] -> Bool
    forall {a}. Ord a => a -> [a] -> Bool
    not_ordered a
    y [a]
    yss -> (Set a
    l, [], [a]
    ys)
                                             | Bool
    otherwise -> case t -> [a] -> (Set a, [a], [a])
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    yss of
                                                       (Set a
    r, [a]
    zs, [a]
    ws) -> (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    l Set a
    r, [a]
    zs, [a]
    ws)
    #if __GLASGOW_HASKELL__
    {-# INLINABLE fromList #-}
    #endif

    {--------------------------------------------------------------------
      Building trees from ascending/descending lists can be done in linear time.

      Note that if [xs] is ascending that:
        fromAscList xs == fromList xs
    --------------------------------------------------------------------}
    -- | \(O(n)\). Build a set from an ascending list in linear time.
    -- /The precondition (input list is ascending) is not checked./
    fromAscList :: Eq a => [a] -> Set a
    fromAscList :: forall a. Eq a => [a] -> Set a
    fromAscList [a]
    xs = [a] -> Set a
    forall a. [a] -> Set a
    fromDistinctAscList ([a] -> [a]
    forall a. Eq a => [a] -> [a]
    combineEq [a]
    xs)
    #if __GLASGOW_HASKELL__
    {-# INLINABLE fromAscList #-}
    #endif

    -- | \(O(n)\). Build a set from a descending list in linear time.
    -- /The precondition (input list is descending) is not checked./
    --
    -- @since 0.5.8
    fromDescList :: Eq a => [a] -> Set a
    fromDescList :: forall a. Eq a => [a] -> Set a
    fromDescList [a]
    xs = [a] -> Set a
    forall a. [a] -> Set a
    fromDistinctDescList ([a] -> [a]
    forall a. Eq a => [a] -> [a]
    combineEq [a]
    xs)
    #if __GLASGOW_HASKELL__
    {-# INLINABLE fromDescList #-}
    #endif

    -- [combineEq xs] combines equal elements with [const] in an ordered list [xs]
    --
    -- TODO: combineEq allocates an intermediate list. It *should* be better to
    -- make fromAscListBy and fromDescListBy the fundamental operations, and to
    -- implement the rest using those.
    combineEq :: Eq a => [a] -> [a]
    combineEq :: forall a. Eq a => [a] -> [a]
    combineEq [] = []
    combineEq (a
    x : [a]
    xs) = a -> [a] -> [a]
    forall {t}. Eq t => t -> [t] -> [t]
    combineEq' a
    x [a]
    xs
      where
        combineEq' :: t -> [t] -> [t]
    combineEq' t
    z [] = [t
    z]
        combineEq' t
    z (t
    y:[t]
    ys)
          | t
    z t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    y = t -> [t] -> [t]
    combineEq' t
    z [t]
    ys
          | Bool
    otherwise = t
    z t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : t -> [t] -> [t]
    combineEq' t
    y [t]
    ys

    -- | \(O(n)\). Build a set from an ascending list of distinct elements in linear time.
    -- /The precondition (input list is strictly ascending) is not checked./

    -- For some reason, when 'singleton' is used in fromDistinctAscList or in
    -- create, it is not inlined, so we inline it manually.
    fromDistinctAscList :: [a] -> Set a
    fromDistinctAscList :: forall a. [a] -> Set a
    fromDistinctAscList [] = Set a
    forall a. Set a
    Tip
    fromDistinctAscList (a
    x0 : [a]
    xs0) = Size -> Set a -> [a] -> Set a
    forall {t} {a}. (Num t, Bits t) => t -> Set a -> [a] -> Set a
    go (Size
    1::Int) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x0 Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) [a]
    xs0
      where
        go :: t -> Set a -> [a] -> Set a
    go !t
    _ Set a
    t [] = Set a
    t
        go t
    s Set a
    l (a
    x : [a]
    xs) = case t -> [a] -> StrictPair (Set a) [a]
    forall {t} {a}.
    (Num t, Bits t) =>
    t -> [a] -> StrictPair (Set a) [a]
    create t
    s [a]
    xs of
                            (Set a
    r :*: [a]
    ys) -> let !t' :: Set a
    t' = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    r
                                          in t -> Set a -> [a] -> Set a
    go (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftL` Size
    1) Set a
    t' [a]
    ys

        create :: t -> [a] -> StrictPair (Set a) [a]
    create !t
    _ [] = (Set a
    forall a. Set a
    Tip Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [])
        create t
    s xs :: [a]
    xs@(a
    x : [a]
    xs')
          | t
    s t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    1 = (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [a]
    xs')
          | Bool
    otherwise = case t -> [a] -> StrictPair (Set a) [a]
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    xs of
                          res :: StrictPair (Set a) [a]
    res@(Set a
    _ :*: []) -> StrictPair (Set a) [a]
    res
                          (Set a
    l :*: (a
    y:[a]
    ys)) -> case t -> [a] -> StrictPair (Set a) [a]
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    ys of
                            (Set a
    r :*: [a]
    zs) -> (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    l Set a
    r Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [a]
    zs)

    -- | \(O(n)\). Build a set from a descending list of distinct elements in linear time.
    -- /The precondition (input list is strictly descending) is not checked./

    -- For some reason, when 'singleton' is used in fromDistinctDescList or in
    -- create, it is not inlined, so we inline it manually.
    --
    -- @since 0.5.8
    fromDistinctDescList :: [a] -> Set a
    fromDistinctDescList :: forall a. [a] -> Set a
    fromDistinctDescList [] = Set a
    forall a. Set a
    Tip
    fromDistinctDescList (a
    x0 : [a]
    xs0) = Size -> Set a -> [a] -> Set a
    forall {t} {a}. (Num t, Bits t) => t -> Set a -> [a] -> Set a
    go (Size
    1::Int) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x0 Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) [a]
    xs0
      where
        go :: t -> Set a -> [a] -> Set a
    go !t
    _ Set a
    t [] = Set a
    t
        go t
    s Set a
    r (a
    x : [a]
    xs) = case t -> [a] -> StrictPair (Set a) [a]
    forall {t} {a}.
    (Num t, Bits t) =>
    t -> [a] -> StrictPair (Set a) [a]
    create t
    s [a]
    xs of
                            (Set a
    l :*: [a]
    ys) -> let !t' :: Set a
    t' = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    r
                                          in t -> Set a -> [a] -> Set a
    go (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftL` Size
    1) Set a
    t' [a]
    ys

        create :: t -> [a] -> StrictPair (Set a) [a]
    create !t
    _ [] = (Set a
    forall a. Set a
    Tip Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [])
        create t
    s xs :: [a]
    xs@(a
    x : [a]
    xs')
          | t
    s t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    1 = (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [a]
    xs')
          | Bool
    otherwise = case t -> [a] -> StrictPair (Set a) [a]
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    xs of
                          res :: StrictPair (Set a) [a]
    res@(Set a
    _ :*: []) -> StrictPair (Set a) [a]
    res
                          (Set a
    r :*: (a
    y:[a]
    ys)) -> case t -> [a] -> StrictPair (Set a) [a]
    create (t
    s t -> Size -> t
    forall a. Bits a => a -> Size -> a
    `shiftR` Size
    1) [a]
    ys of
                            (Set a
    l :*: [a]
    zs) -> (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    l Set a
    r Set a -> [a] -> StrictPair (Set a) [a]
    forall a b. a -> b -> StrictPair a b
    :*: [a]
    zs)

    {--------------------------------------------------------------------
      Eq converts the set to a list. In a lazy setting, this
      actually seems one of the faster methods to compare two trees
      and it is certainly the simplest :-)
    --------------------------------------------------------------------}
    instance Eq a => Eq (Set a) where
      Set a
    t1 == :: Set a -> Set a -> Bool
    == Set a
    t2  = (Set a -> Size
    forall a. Set a -> Size
    size Set a
    t1 Size -> Size -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> Size
    forall a. Set a -> Size
    size Set a
    t2) Bool -> Bool -> Bool
    && (Set a -> [a]
    forall a. Set a -> [a]
    toAscList Set a
    t1 [a] -> [a] -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> [a]
    forall a. Set a -> [a]
    toAscList Set a
    t2)

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

    instance Ord a => Ord (Set a) where
        compare :: Set a -> Set a -> Ordering
    compare Set a
    s1 Set a
    s2 = [a] -> [a] -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Set a -> [a]
    forall a. Set a -> [a]
    toAscList Set a
    s1) (Set a -> [a]
    forall a. Set a -> [a]
    toAscList Set a
    s2)

    {--------------------------------------------------------------------
      Show
    --------------------------------------------------------------------}
    instance Show a => Show (Set a) where
      showsPrec :: Size -> Set a -> ShowS
    showsPrec Size
    p Set a
    xs = Bool -> ShowS -> ShowS
    showParen (Size
    p Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    > Size
    10) (ShowS -> ShowS) -> ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $
        [Char] -> ShowS
    showString [Char]
    "fromList " ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> ShowS
    forall a. Show a => a -> ShowS
    shows (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    xs)

    -- | @since 0.5.9
    instance Eq1 Set where
        liftEq :: forall a b. (a -> b -> Bool) -> Set a -> Set b -> Bool
    liftEq a -> b -> Bool
    eq Set a
    m Set b
    n =
            Set a -> Size
    forall a. Set a -> Size
    size Set a
    m Size -> Size -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set b -> Size
    forall a. Set a -> Size
    size Set b
    n Bool -> Bool -> Bool
    && (a -> b -> Bool) -> [a] -> [b] -> Bool
    forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
    forall (f :: * -> *) a b.
    Eq1 f =>
    (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq a -> b -> Bool
    eq (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    m) (Set b -> [b]
    forall a. Set a -> [a]
    toList Set b
    n)

    -- | @since 0.5.9
    instance Ord1 Set where
        liftCompare :: forall a b. (a -> b -> Ordering) -> Set a -> Set b -> Ordering
    liftCompare a -> b -> Ordering
    cmp Set a
    m Set b
    n =
            (a -> b -> Ordering) -> [a] -> [b] -> Ordering
    forall a b. (a -> b -> Ordering) -> [a] -> [b] -> Ordering
    forall (f :: * -> *) a b.
    Ord1 f =>
    (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare a -> b -> Ordering
    cmp (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    m) (Set b -> [b]
    forall a. Set a -> [a]
    toList Set b
    n)

    -- | @since 0.5.9
    instance Show1 Set where
        liftShowsPrec :: forall a.
    (Size -> a -> ShowS) -> ([a] -> ShowS) -> Size -> Set a -> ShowS
    liftShowsPrec Size -> a -> ShowS
    sp [a] -> ShowS
    sl Size
    d Set a
    m =
            (Size -> [a] -> ShowS) -> [Char] -> Size -> [a] -> ShowS
    forall a. (Size -> a -> ShowS) -> [Char] -> Size -> a -> ShowS
    showsUnaryWith ((Size -> a -> ShowS) -> ([a] -> ShowS) -> Size -> [a] -> ShowS
    forall a.
    (Size -> a -> ShowS) -> ([a] -> ShowS) -> Size -> [a] -> ShowS
    forall (f :: * -> *) a.
    Show1 f =>
    (Size -> a -> ShowS) -> ([a] -> ShowS) -> Size -> f a -> ShowS
    liftShowsPrec Size -> a -> ShowS
    sp [a] -> ShowS
    sl) [Char]
    "fromList" Size
    d (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    m)

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

      readListPrec :: ReadPrec [Set a]
    readListPrec = ReadPrec [Set a]
    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

    {--------------------------------------------------------------------
      NFData
    --------------------------------------------------------------------}

    instance NFData a => NFData (Set a) where
        rnf :: Set a -> ()
    rnf Set a
    Tip           = ()
        rnf (Bin Size
    _ a
    y Set a
    l Set a
    r) = a -> ()
    forall a. NFData a => a -> ()
    rnf a
    y () -> () -> ()
    forall a b. a -> b -> b
    `seq` Set a -> ()
    forall a. NFData a => a -> ()
    rnf Set a
    l () -> () -> ()
    forall a b. a -> b -> b
    `seq` Set a -> ()
    forall a. NFData a => a -> ()
    rnf Set a
    r

    {--------------------------------------------------------------------
      Split
    --------------------------------------------------------------------}
    -- | \(O(\log n)\). The expression (@'split' x set@) is a pair @(set1,set2)@
    -- where @set1@ comprises the elements of @set@ less than @x@ and @set2@
    -- comprises the elements of @set@ greater than @x@.
    split :: Ord a => a -> Set a -> (Set a,Set a)
    split :: forall a. Ord a => a -> Set a -> (Set a, Set a)
    split a
    x Set a
    t = StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair (StrictPair (Set a) (Set a) -> (Set a, Set a))
    -> StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. (a -> b) -> a -> b
    $ a -> Set a -> StrictPair (Set a) (Set a)
    forall a. Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS a
    x Set a
    t
    {-# INLINABLE split #-}

    splitS :: Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS :: forall a. Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS a
    _ Set a
    Tip = (Set a
    forall a. Set a
    Tip Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    forall a. Set a
    Tip)
    splitS a
    x (Bin Size
    _ a
    y Set a
    l Set a
    r)
          = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
              Ordering
    LT -> let (Set a
    lt :*: Set a
    gt) = a -> Set a -> StrictPair (Set a) (Set a)
    forall a. Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS a
    x Set a
    l in (Set a
    lt Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    gt Set a
    r)
              Ordering
    GT -> let (Set a
    lt :*: Set a
    gt) = a -> Set a -> StrictPair (Set a) (Set a)
    forall a. Ord a => a -> Set a -> StrictPair (Set a) (Set a)
    splitS a
    x Set a
    r in (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    l Set a
    lt Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    gt)
              Ordering
    EQ -> (Set a
    l Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    r)
    {-# INLINABLE splitS #-}

    -- | \(O(\log n)\). Performs a 'split' but also returns whether the pivot
    -- element was found in the original set.
    splitMember :: Ord a => a -> Set a -> (Set a,Bool,Set a)
    splitMember :: forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    _ Set a
    Tip = (Set a
    forall a. Set a
    Tip, Bool
    False, Set a
    forall a. Set a
    Tip)
    splitMember a
    x (Bin Size
    _ a
    y Set a
    l Set a
    r)
       = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
           Ordering
    LT -> let (Set a
    lt, Bool
    found, Set a
    gt) = a -> Set a -> (Set a, Bool, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    x Set a
    l
                     !gt' :: Set a
    gt' = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    gt Set a
    r
                 in (Set a
    lt, Bool
    found, Set a
    gt')
           Ordering
    GT -> let (Set a
    lt, Bool
    found, Set a
    gt) = a -> Set a -> (Set a, Bool, Set a)
    forall a. Ord a => a -> Set a -> (Set a, Bool, Set a)
    splitMember a
    x Set a
    r
                     !lt' :: Set a
    lt' = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    y Set a
    l Set a
    lt
                 in (Set a
    lt', Bool
    found, Set a
    gt)
           Ordering
    EQ -> (Set a
    l, Bool
    True, Set a
    r)
    #if __GLASGOW_HASKELL__
    {-# INLINABLE splitMember #-}
    #endif

    {--------------------------------------------------------------------
      Indexing
    --------------------------------------------------------------------}

    -- | \(O(\log n)\). Return the /index/ of an element, which is its zero-based
    -- index in the sorted sequence of elements. The index is a number from /0/ up
    -- to, but not including, the 'size' of the set. Calls 'error' when the element
    -- is not a 'member' of the set.
    --
    -- > findIndex 2 (fromList [5,3])    Error: element is not in the set
    -- > findIndex 3 (fromList [5,3]) == 0
    -- > findIndex 5 (fromList [5,3]) == 1
    -- > findIndex 6 (fromList [5,3])    Error: element is not in the set
    --
    -- @since 0.5.4

    -- See Note: Type of local 'go' function
    findIndex :: Ord a => a -> Set a -> Int
    findIndex :: forall a. Ord a => a -> Set a -> Size
    findIndex = Size -> a -> Set a -> Size
    forall a. Ord a => Size -> a -> Set a -> Size
    go Size
    0
      where
        go :: Ord a => Int -> a -> Set a -> Int
        go :: forall a. Ord a => Size -> a -> Set a -> Size
    go !Size
    _ !a
    _ Set a
    Tip  = [Char] -> Size
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.findIndex: element is not in the set"
        go Size
    idx a
    x (Bin Size
    _ a
    kx Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    kx of
          Ordering
    LT -> Size -> a -> Set a -> Size
    forall a. Ord a => Size -> a -> Set a -> Size
    go Size
    idx a
    x Set a
    l
          Ordering
    GT -> Size -> a -> Set a -> Size
    forall a. Ord a => Size -> a -> Set a -> Size
    go (Size
    idx Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Size
    1) a
    x Set a
    r
          Ordering
    EQ -> Size
    idx Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    l
    #if __GLASGOW_HASKELL__
    {-# INLINABLE findIndex #-}
    #endif

    -- | \(O(\log n)\). Lookup the /index/ of an element, which is its zero-based index in
    -- the sorted sequence of elements. The index is a number from /0/ up to, but not
    -- including, the 'size' of the set.
    --
    -- > isJust   (lookupIndex 2 (fromList [5,3])) == False
    -- > fromJust (lookupIndex 3 (fromList [5,3])) == 0
    -- > fromJust (lookupIndex 5 (fromList [5,3])) == 1
    -- > isJust   (lookupIndex 6 (fromList [5,3])) == False
    --
    -- @since 0.5.4

    -- See Note: Type of local 'go' function
    lookupIndex :: Ord a => a -> Set a -> Maybe Int
    lookupIndex :: forall a. Ord a => a -> Set a -> Maybe Size
    lookupIndex = Size -> a -> Set a -> Maybe Size
    forall a. Ord a => Size -> a -> Set a -> Maybe Size
    go Size
    0
      where
        go :: Ord a => Int -> a -> Set a -> Maybe Int
        go :: forall a. Ord a => Size -> a -> Set a -> Maybe Size
    go !Size
    _ !a
    _ Set a
    Tip  = Maybe Size
    forall a. Maybe a
    Nothing
        go Size
    idx a
    x (Bin Size
    _ a
    kx Set a
    l Set a
    r) = case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    kx of
          Ordering
    LT -> Size -> a -> Set a -> Maybe Size
    forall a. Ord a => Size -> a -> Set a -> Maybe Size
    go Size
    idx a
    x Set a
    l
          Ordering
    GT -> Size -> a -> Set a -> Maybe Size
    forall a. Ord a => Size -> a -> Set a -> Maybe Size
    go (Size
    idx Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Size
    1) a
    x Set a
    r
          Ordering
    EQ -> Size -> Maybe Size
    forall a. a -> Maybe a
    Just (Size -> Maybe Size) -> Size -> Maybe Size
    forall a b. (a -> b) -> a -> b
    $! Size
    idx Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    l
    #if __GLASGOW_HASKELL__
    {-# INLINABLE lookupIndex #-}
    #endif

    -- | \(O(\log n)\). Retrieve an element by its /index/, i.e. by its zero-based
    -- index in the sorted sequence of elements. If the /index/ is out of range (less
    -- than zero, greater or equal to 'size' of the set), 'error' is called.
    --
    -- > elemAt 0 (fromList [5,3]) == 3
    -- > elemAt 1 (fromList [5,3]) == 5
    -- > elemAt 2 (fromList [5,3])    Error: index out of range
    --
    -- @since 0.5.4

    elemAt :: Int -> Set a -> a
    elemAt :: forall a. Size -> Set a -> a
    elemAt !Size
    _ Set a
    Tip = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.elemAt: index out of range"
    elemAt Size
    i (Bin Size
    _ a
    x Set a
    l Set a
    r)
      = case Size -> Size -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Size
    i Size
    sizeL of
          Ordering
    LT -> Size -> Set a -> a
    forall a. Size -> Set a -> a
    elemAt Size
    i Set a
    l
          Ordering
    GT -> Size -> Set a -> a
    forall a. Size -> Set a -> a
    elemAt (Size
    iSize -> Size -> Size
    forall a. Num a => a -> a -> a
    -Size
    sizeLSize -> Size -> Size
    forall a. Num a => a -> a -> a
    -Size
    1) Set a
    r
          Ordering
    EQ -> a
    x
      where
        sizeL :: Size
    sizeL = Set a -> Size
    forall a. Set a -> Size
    size Set a
    l

    -- | \(O(\log n)\). Delete the element at /index/, i.e. by its zero-based index in
    -- the sorted sequence of elements. If the /index/ is out of range (less than zero,
    -- greater or equal to 'size' of the set), 'error' is called.
    --
    -- > deleteAt 0    (fromList [5,3]) == singleton 5
    -- > deleteAt 1    (fromList [5,3]) == singleton 3
    -- > deleteAt 2    (fromList [5,3])    Error: index out of range
    -- > deleteAt (-1) (fromList [5,3])    Error: index out of range
    --
    -- @since 0.5.4

    deleteAt :: Int -> Set a -> Set a
    deleteAt :: forall a. Size -> Set a -> Set a
    deleteAt !Size
    i Set a
    t =
      case Set a
    t of
        Set a
    Tip -> [Char] -> Set a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.deleteAt: index out of range"
        Bin Size
    _ a
    x Set a
    l Set a
    r -> case Size -> Size -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Size
    i Size
    sizeL of
          Ordering
    LT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    x (Size -> Set a -> Set a
    forall a. Size -> Set a -> Set a
    deleteAt Size
    i Set a
    l) Set a
    r
          Ordering
    GT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    x Set a
    l (Size -> Set a -> Set a
    forall a. Size -> Set a -> Set a
    deleteAt (Size
    iSize -> Size -> Size
    forall a. Num a => a -> a -> a
    -Size
    sizeLSize -> Size -> Size
    forall a. Num a => a -> a -> a
    -Size
    1) Set a
    r)
          Ordering
    EQ -> Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    glue Set a
    l Set a
    r
          where
            sizeL :: Size
    sizeL = Set a -> Size
    forall a. Set a -> Size
    size Set a
    l

    -- | \(O(\log n)\). Take a given number of elements in order, beginning
    -- with the smallest ones.
    --
    -- @
    -- take n = 'fromDistinctAscList' . 'Prelude.take' n . 'toAscList'
    -- @
    --
    -- @since 0.5.8
    take :: Int -> Set a -> Set a
    take :: forall a. Size -> Set a -> Set a
    take Size
    i Set a
    m | Size
    i Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Size
    forall a. Set a -> Size
    size Set a
    m = Set a
    m
    take Size
    i0 Set a
    m0 = Size -> Set a -> Set a
    forall a. Size -> Set a -> Set a
    go Size
    i0 Set a
    m0
      where
        go :: Size -> Set a -> Set a
    go Size
    i !Set a
    _ | Size
    i Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    0 = Set a
    forall a. Set a
    Tip
        go !Size
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
        go Size
    i (Bin Size
    _ a
    x Set a
    l Set a
    r) =
          case Size -> Size -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Size
    i Size
    sizeL of
            Ordering
    LT -> Size -> Set a -> Set a
    go Size
    i Set a
    l
            Ordering
    GT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l (Size -> Set a -> Set a
    go (Size
    i Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    sizeL Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    1) Set a
    r)
            Ordering
    EQ -> Set a
    l
          where sizeL :: Size
    sizeL = Set a -> Size
    forall a. Set a -> Size
    size Set a
    l

    -- | \(O(\log n)\). Drop a given number of elements in order, beginning
    -- with the smallest ones.
    --
    -- @
    -- drop n = 'fromDistinctAscList' . 'Prelude.drop' n . 'toAscList'
    -- @
    --
    -- @since 0.5.8
    drop :: Int -> Set a -> Set a
    drop :: forall a. Size -> Set a -> Set a
    drop Size
    i Set a
    m | Size
    i Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Size
    forall a. Set a -> Size
    size Set a
    m = Set a
    forall a. Set a
    Tip
    drop Size
    i0 Set a
    m0 = Size -> Set a -> Set a
    forall a. Size -> Set a -> Set a
    go Size
    i0 Set a
    m0
      where
        go :: Size -> Set a -> Set a
    go Size
    i Set a
    m | Size
    i Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    0 = Set a
    m
        go !Size
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
        go Size
    i (Bin Size
    _ a
    x Set a
    l Set a
    r) =
          case Size -> Size -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Size
    i Size
    sizeL of
            Ordering
    LT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x (Size -> Set a -> Set a
    go Size
    i Set a
    l) Set a
    r
            Ordering
    GT -> Size -> Set a -> Set a
    go (Size
    i Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    sizeL Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    1) Set a
    r
            Ordering
    EQ -> a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMin a
    x Set a
    r
          where sizeL :: Size
    sizeL = Set a -> Size
    forall a. Set a -> Size
    size Set a
    l

    -- | \(O(\log n)\). Split a set at a particular index.
    --
    -- @
    -- splitAt !n !xs = ('take' n xs, 'drop' n xs)
    -- @
    splitAt :: Int -> Set a -> (Set a, Set a)
    splitAt :: forall a. Size -> Set a -> (Set a, Set a)
    splitAt Size
    i0 Set a
    m0
      | Size
    i0 Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Size
    forall a. Set a -> Size
    size Set a
    m0 = (Set a
    m0, Set a
    forall a. Set a
    Tip)
      | Bool
    otherwise = StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair (StrictPair (Set a) (Set a) -> (Set a, Set a))
    -> StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. (a -> b) -> a -> b
    $ Size -> Set a -> StrictPair (Set a) (Set a)
    forall {a}. Size -> Set a -> StrictPair (Set a) (Set a)
    go Size
    i0 Set a
    m0
      where
        go :: Size -> Set a -> StrictPair (Set a) (Set a)
    go Size
    i Set a
    m | Size
    i Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    0 = Set a
    forall a. Set a
    Tip Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    m
        go !Size
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    forall a. Set a
    Tip
        go Size
    i (Bin Size
    _ a
    x Set a
    l Set a
    r)
          = case Size -> Size -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Size
    i Size
    sizeL of
              Ordering
    LT -> case Size -> Set a -> StrictPair (Set a) (Set a)
    go Size
    i Set a
    l of
                      Set a
    ll :*: Set a
    lr -> Set a
    ll Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    lr Set a
    r
              Ordering
    GT -> case Size -> Set a -> StrictPair (Set a) (Set a)
    go (Size
    i Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    sizeL Size -> Size -> Size
    forall a. Num a => a -> a -> a
    - Size
    1) Set a
    r of
                      Set a
    rl :*: Set a
    rr -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    rl Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    rr
              Ordering
    EQ -> Set a
    l Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMin a
    x Set a
    r
          where sizeL :: Size
    sizeL = Set a -> Size
    forall a. Set a -> Size
    size Set a
    l

    -- | \(O(\log n)\). Take while a predicate on the elements holds.
    -- The user is responsible for ensuring that for all elements @j@ and @k@ in the set,
    -- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.
    --
    -- @
    -- takeWhileAntitone p = 'fromDistinctAscList' . 'Data.List.takeWhile' p . 'toList'
    -- takeWhileAntitone p = 'filter' p
    -- @
    --
    -- @since 0.5.8

    takeWhileAntitone :: (a -> Bool) -> Set a -> Set a
    takeWhileAntitone :: forall a. (a -> Bool) -> Set a -> Set a
    takeWhileAntitone a -> Bool
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
    takeWhileAntitone a -> Bool
    p (Bin Size
    _ a
    x Set a
    l Set a
    r)
      | a -> Bool
    p a
    x = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l ((a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    takeWhileAntitone a -> Bool
    p Set a
    r)
      | Bool
    otherwise = (a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    takeWhileAntitone a -> Bool
    p Set a
    l

    -- | \(O(\log n)\). Drop while a predicate on the elements holds.
    -- The user is responsible for ensuring that for all elements @j@ and @k@ in the set,
    -- @j \< k ==\> p j \>= p k@. See note at 'spanAntitone'.
    --
    -- @
    -- dropWhileAntitone p = 'fromDistinctAscList' . 'Data.List.dropWhile' p . 'toList'
    -- dropWhileAntitone p = 'filter' (not . p)
    -- @
    --
    -- @since 0.5.8

    dropWhileAntitone :: (a -> Bool) -> Set a -> Set a
    dropWhileAntitone :: forall a. (a -> Bool) -> Set a -> Set a
    dropWhileAntitone a -> Bool
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
    dropWhileAntitone a -> Bool
    p (Bin Size
    _ a
    x Set a
    l Set a
    r)
      | a -> Bool
    p a
    x = (a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    dropWhileAntitone a -> Bool
    p Set a
    r
      | Bool
    otherwise = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x ((a -> Bool) -> Set a -> Set a
    forall a. (a -> Bool) -> Set a -> Set a
    dropWhileAntitone a -> Bool
    p Set a
    l) Set a
    r

    -- | \(O(\log n)\). Divide a set at the point where a predicate on the elements stops holding.
    -- The user is responsible for ensuring that for all elements @j@ and @k@ in the set,
    -- @j \< k ==\> p j \>= p k@.
    --
    -- @
    -- spanAntitone p xs = ('takeWhileAntitone' p xs, 'dropWhileAntitone' p xs)
    -- spanAntitone p xs = partition p xs
    -- @
    --
    -- Note: if @p@ is not actually antitone, then @spanAntitone@ will split the set
    -- at some /unspecified/ point where the predicate switches from holding to not
    -- holding (where the predicate is seen to hold before the first element and to fail
    -- after the last element).
    --
    -- @since 0.5.8

    spanAntitone :: (a -> Bool) -> Set a -> (Set a, Set a)
    spanAntitone :: forall a. (a -> Bool) -> Set a -> (Set a, Set a)
    spanAntitone a -> Bool
    p0 Set a
    m = StrictPair (Set a) (Set a) -> (Set a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair ((a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    forall {a}. (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p0 Set a
    m)
      where
        go :: (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    forall a. Set a
    Tip
        go a -> Bool
    p (Bin Size
    _ a
    x Set a
    l Set a
    r)
          | a -> Bool
    p a
    x = let Set a
    u :*: Set a
    v = (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p Set a
    r in a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    u Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: Set a
    v
          | Bool
    otherwise = let Set a
    u :*: Set a
    v = (a -> Bool) -> Set a -> StrictPair (Set a) (Set a)
    go a -> Bool
    p Set a
    l in Set a
    u Set a -> Set a -> StrictPair (Set a) (Set a)
    forall a b. a -> b -> StrictPair a b
    :*: a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    v Set a
    r

    {--------------------------------------------------------------------
      Utility functions that maintain the balance properties of the tree.
      All constructors assume that all values in [l] < [x] and all values
      in [r] > [x], and that [l] and [r] are valid trees.

      In order of sophistication:
        [Bin sz x l r]    The type constructor.
        [bin x l r]       Maintains the correct size, assumes that both [l]
                          and [r] are balanced with respect to each other.
        [balance x l r]   Restores the balance and size.
                          Assumes that the original tree was balanced and
                          that [l] or [r] has changed by at most one element.
        [link x l r]      Restores balance and size.

      Furthermore, we can construct a new tree from two trees. Both operations
      assume that all values in [l] < all values in [r] and that [l] and [r]
      are valid:
        [glue l r]        Glues [l] and [r] together. Assumes that [l] and
                          [r] are already balanced with respect to each other.
        [merge l r]       Merges two trees and restores balance.
    --------------------------------------------------------------------}

    {--------------------------------------------------------------------
      Link
    --------------------------------------------------------------------}
    link :: a -> Set a -> Set a -> Set a
    link :: forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    Tip Set a
    r  = a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMin a
    x Set a
    r
    link a
    x Set a
    l Set a
    Tip  = a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMax a
    x Set a
    l
    link a
    x l :: Set a
    l@(Bin Size
    sizeL a
    y Set a
    ly Set a
    ry) r :: Set a
    r@(Bin Size
    sizeR a
    z Set a
    lz Set a
    rz)
      | Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    sizeL Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    sizeR  = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    z (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    l Set a
    lz) Set a
    rz
      | Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    sizeR Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    sizeL  = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    ly (a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x Set a
    ry Set a
    r)
      | Bool
    otherwise            = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    bin a
    x Set a
    l Set a
    r

    -- insertMin and insertMax don't perform potentially expensive comparisons.
    insertMax,insertMin :: a -> Set a -> Set a
    insertMax :: forall a. a -> Set a -> Set a
    insertMax a
    x Set a
    t
      = case Set a
    t of
          Set a
    Tip -> a -> Set a
    forall a. a -> Set a
    singleton a
    x
          Bin Size
    _ a
    y Set a
    l Set a
    r
              -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    y Set a
    l (a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMax a
    x Set a
    r)

    insertMin :: forall a. a -> Set a -> Set a
    insertMin a
    x Set a
    t
      = case Set a
    t of
          Set a
    Tip -> a -> Set a
    forall a. a -> Set a
    singleton a
    x
          Bin Size
    _ a
    y Set a
    l Set a
    r
              -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y (a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMin a
    x Set a
    l) Set a
    r

    {--------------------------------------------------------------------
      [merge l r]: merges two trees.
    --------------------------------------------------------------------}
    merge :: Set a -> Set a -> Set a
    merge :: forall a. Set a -> Set a -> Set a
    merge Set a
    Tip Set a
    r   = Set a
    r
    merge Set a
    l Set a
    Tip   = Set a
    l
    merge l :: Set a
    l@(Bin Size
    sizeL a
    x Set a
    lx Set a
    rx) r :: Set a
    r@(Bin Size
    sizeR a
    y Set a
    ly Set a
    ry)
      | Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    sizeL Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    sizeR = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    y (Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    l Set a
    ly) Set a
    ry
      | Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    sizeR Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    sizeL = a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    x Set a
    lx (Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    rx Set a
    r)
      | Bool
    otherwise           = Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    glue Set a
    l Set a
    r

    {--------------------------------------------------------------------
      [glue l r]: glues two trees together.
      Assumes that [l] and [r] are already balanced with respect to each other.
    --------------------------------------------------------------------}
    glue :: Set a -> Set a -> Set a
    glue :: forall a. Set a -> Set a -> Set a
    glue Set a
    Tip Set a
    r = Set a
    r
    glue Set a
    l Set a
    Tip = Set a
    l
    glue l :: Set a
    l@(Bin Size
    sl a
    xl Set a
    ll Set a
    lr) r :: Set a
    r@(Bin Size
    sr a
    xr Set a
    rl Set a
    rr)
      | Size
    sl Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    > Size
    sr = let !(a
    m :*: Set a
    l') = a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    maxViewSure a
    xl Set a
    ll Set a
    lr in a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    m Set a
    l' Set a
    r
      | Bool
    otherwise = let !(a
    m :*: Set a
    r') = a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    minViewSure a
    xr Set a
    rl Set a
    rr in a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceL a
    m Set a
    l Set a
    r'

    -- | \(O(\log n)\). Delete and find the minimal element.
    --
    -- > deleteFindMin set = (findMin set, deleteMin set)

    deleteFindMin :: Set a -> (a,Set a)
    deleteFindMin :: forall a. Set a -> (a, Set a)
    deleteFindMin Set a
    t
      | Just (a, Set a)
    r <- Set a -> Maybe (a, Set a)
    forall a. Set a -> Maybe (a, Set a)
    minView Set a
    t = (a, Set a)
    r
      | Bool
    otherwise = ([Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.deleteFindMin: can not return the minimal element of an empty set", Set a
    forall a. Set a
    Tip)

    -- | \(O(\log n)\). Delete and find the maximal element.
    --
    -- > deleteFindMax set = (findMax set, deleteMax set)
    deleteFindMax :: Set a -> (a,Set a)
    deleteFindMax :: forall a. Set a -> (a, Set a)
    deleteFindMax Set a
    t
      | Just (a, Set a)
    r <- Set a -> Maybe (a, Set a)
    forall a. Set a -> Maybe (a, Set a)
    maxView Set a
    t = (a, Set a)
    r
      | Bool
    otherwise = ([Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.deleteFindMax: can not return the maximal element of an empty set", Set a
    forall a. Set a
    Tip)

    minViewSure :: a -> Set a -> Set a -> StrictPair a (Set a)
    minViewSure :: forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    minViewSure = a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    go
      where
        go :: t -> Set t -> Set t -> StrictPair t (Set t)
    go t
    x Set t
    Tip Set t
    r = t
    x t -> Set t -> StrictPair t (Set t)
    forall a b. a -> b -> StrictPair a b
    :*: Set t
    r
        go t
    x (Bin Size
    _ t
    xl Set t
    ll Set t
    lr) Set t
    r =
          case t -> Set t -> Set t -> StrictPair t (Set t)
    go t
    xl Set t
    ll Set t
    lr of
            t
    xm :*: Set t
    l' -> t
    xm t -> Set t -> StrictPair t (Set t)
    forall a b. a -> b -> StrictPair a b
    :*: t -> Set t -> Set t -> Set t
    forall a. a -> Set a -> Set a -> Set a
    balanceR t
    x Set t
    l' Set t
    r

    -- | \(O(\log n)\). Retrieves the minimal key of the set, and the set
    -- stripped of that element, or 'Nothing' if passed an empty set.
    minView :: Set a -> Maybe (a, Set a)
    minView :: forall a. Set a -> Maybe (a, Set a)
    minView Set a
    Tip = Maybe (a, Set a)
    forall a. Maybe a
    Nothing
    minView (Bin Size
    _ a
    x Set a
    l Set a
    r) = (a, Set a) -> Maybe (a, Set a)
    forall a. a -> Maybe a
    Just ((a, Set a) -> Maybe (a, Set a)) -> (a, Set a) -> Maybe (a, Set a)
    forall a b. (a -> b) -> a -> b
    $! StrictPair a (Set a) -> (a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair (StrictPair a (Set a) -> (a, Set a))
    -> StrictPair a (Set a) -> (a, Set a)
    forall a b. (a -> b) -> a -> b
    $ a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    minViewSure a
    x Set a
    l Set a
    r

    maxViewSure :: a -> Set a -> Set a -> StrictPair a (Set a)
    maxViewSure :: forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    maxViewSure = a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    go
      where
        go :: t -> Set t -> Set t -> StrictPair t (Set t)
    go t
    x Set t
    l Set t
    Tip = t
    x t -> Set t -> StrictPair t (Set t)
    forall a b. a -> b -> StrictPair a b
    :*: Set t
    l
        go t
    x Set t
    l (Bin Size
    _ t
    xr Set t
    rl Set t
    rr) =
          case t -> Set t -> Set t -> StrictPair t (Set t)
    go t
    xr Set t
    rl Set t
    rr of
            t
    xm :*: Set t
    r' -> t
    xm t -> Set t -> StrictPair t (Set t)
    forall a b. a -> b -> StrictPair a b
    :*: t -> Set t -> Set t -> Set t
    forall a. a -> Set a -> Set a -> Set a
    balanceL t
    x Set t
    l Set t
    r'

    -- | \(O(\log n)\). Retrieves the maximal key of the set, and the set
    -- stripped of that element, or 'Nothing' if passed an empty set.
    maxView :: Set a -> Maybe (a, Set a)
    maxView :: forall a. Set a -> Maybe (a, Set a)
    maxView Set a
    Tip = Maybe (a, Set a)
    forall a. Maybe a
    Nothing
    maxView (Bin Size
    _ a
    x Set a
    l Set a
    r) = (a, Set a) -> Maybe (a, Set a)
    forall a. a -> Maybe a
    Just ((a, Set a) -> Maybe (a, Set a)) -> (a, Set a) -> Maybe (a, Set a)
    forall a b. (a -> b) -> a -> b
    $! StrictPair a (Set a) -> (a, Set a)
    forall a b. StrictPair a b -> (a, b)
    toPair (StrictPair a (Set a) -> (a, Set a))
    -> StrictPair a (Set a) -> (a, Set a)
    forall a b. (a -> b) -> a -> b
    $ a -> Set a -> Set a -> StrictPair a (Set a)
    forall a. a -> Set a -> Set a -> StrictPair a (Set a)
    maxViewSure a
    x Set a
    l Set a
    r

    {--------------------------------------------------------------------
      [balance x l r] balances two trees with value x.
      The sizes of the trees should balance after decreasing the
      size of one of them. (a rotation).

      [delta] is the maximal relative difference between the sizes of
              two trees, it corresponds with the [w] in Adams' paper.
      [ratio] is the ratio between an outer and inner sibling of the
              heavier subtree in an unbalanced setting. It determines
              whether a double or single rotation should be performed
              to restore balance. It is corresponds with the inverse
              of $\alpha$ in Adam's article.

      Note that according to the Adam's paper:
      - [delta] should be larger than 4.646 with a [ratio] of 2.
      - [delta] should be larger than 3.745 with a [ratio] of 1.534.

      But the Adam's paper is erroneous:
      - it can be proved that for delta=2 and delta>=5 there does
        not exist any ratio that would work
      - delta=4.5 and ratio=2 does not work

      That leaves two reasonable variants, delta=3 and delta=4,
      both with ratio=2.

      - A lower [delta] leads to a more 'perfectly' balanced tree.
      - A higher [delta] performs less rebalancing.

      In the benchmarks, delta=3 is faster on insert operations,
      and delta=4 has slightly better deletes. As the insert speedup
      is larger, we currently use delta=3.

    --------------------------------------------------------------------}
    delta,ratio :: Int
    delta :: Size
    delta = Size
    3
    ratio :: Size
    ratio = Size
    2

    -- The balance function is equivalent to the following:
    --
    --   balance :: a -> Set a -> Set a -> Set a
    --   balance x l r
    --     | sizeL + sizeR <= 1   = Bin sizeX x l r
    --     | sizeR > delta*sizeL  = rotateL x l r
    --     | sizeL > delta*sizeR  = rotateR x l r
    --     | otherwise            = Bin sizeX x l r
    --     where
    --       sizeL = size l
    --       sizeR = size r
    --       sizeX = sizeL + sizeR + 1
    --
    --   rotateL :: a -> Set a -> Set a -> Set a
    --   rotateL x l r@(Bin _ _ ly ry) | size ly < ratio*size ry = singleL x l r
    --                                 | otherwise               = doubleL x l r
    --   rotateR :: a -> Set a -> Set a -> Set a
    --   rotateR x l@(Bin _ _ ly ry) r | size ry < ratio*size ly = singleR x l r
    --                                 | otherwise               = doubleR x l r
    --
    --   singleL, singleR :: a -> Set a -> Set a -> Set a
    --   singleL x1 t1 (Bin _ x2 t2 t3)  = bin x2 (bin x1 t1 t2) t3
    --   singleR x1 (Bin _ x2 t1 t2) t3  = bin x2 t1 (bin x1 t2 t3)
    --
    --   doubleL, doubleR :: a -> Set a -> Set a -> Set a
    --   doubleL x1 t1 (Bin _ x2 (Bin _ x3 t2 t3) t4) = bin x3 (bin x1 t1 t2) (bin x2 t3 t4)
    --   doubleR x1 (Bin _ x2 t1 (Bin _ x3 t2 t3)) t4 = bin x3 (bin x2 t1 t2) (bin x1 t3 t4)
    --
    -- It is only written in such a way that every node is pattern-matched only once.
    --
    -- Only balanceL and balanceR are needed at the moment, so balance is not here anymore.
    -- In case it is needed, it can be found in Data.Map.

    -- Functions balanceL and balanceR are specialised versions of balance.
    -- balanceL only checks whether the left subtree is too big,
    -- balanceR only checks whether the right subtree is too big.

    -- balanceL is called when left subtree might have been inserted to or when
    -- right subtree might have been deleted from.
    balanceL :: a -> Set a -> Set a -> Set a
    balanceL :: forall a. a -> Set a -> Set a -> Set a
    balanceL a
    x Set a
    l Set a
    r = case Set a
    r of
      Set a
    Tip -> case Set a
    l of
               Set a
    Tip -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
               (Bin Size
    _ a
    _ Set a
    Tip Set a
    Tip) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    2 a
    x Set a
    l Set a
    forall a. Set a
    Tip
               (Bin Size
    _ a
    lx Set a
    Tip (Bin Size
    _ a
    lrx Set a
    _ Set a
    _)) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    3 a
    lrx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    lx Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Size
    _ a
    lx ll :: Set a
    ll@(Bin Size
    _ a
    _ Set a
    _ Set a
    _) Set a
    Tip) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    3 a
    lx Set a
    ll (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Size
    ls a
    lx ll :: Set a
    ll@(Bin Size
    lls a
    _ Set a
    _ Set a
    _) lr :: Set a
    lr@(Bin Size
    lrs a
    lrx Set a
    lrl Set a
    lrr))
                 | Size
    lrs Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    ratioSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    lls -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    ls) a
    lx Set a
    ll (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lrs) a
    x Set a
    lr Set a
    forall a. Set a
    Tip)
                 | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    ls) a
    lrx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    llsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    lrl) a
    lx Set a
    ll Set a
    lrl) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    lrr) a
    x Set a
    lrr Set a
    forall a. Set a
    Tip)

      (Bin Size
    rs a
    _ Set a
    _ Set a
    _) -> case Set a
    l of
               Set a
    Tip -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    x Set a
    forall a. Set a
    Tip Set a
    r

               (Bin Size
    ls a
    lx Set a
    ll Set a
    lr)
                  | Size
    ls Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    > Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    rs  -> case (Set a
    ll, Set a
    lr) of
                       (Bin Size
    lls a
    _ Set a
    _ Set a
    _, Bin Size
    lrs a
    lrx Set a
    lrl Set a
    lrr)
                         | Size
    lrs Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    ratioSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    lls -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    lx Set a
    ll (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lrs) a
    x Set a
    lr Set a
    r)
                         | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    lrx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    llsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    lrl) a
    lx Set a
    ll Set a
    lrl) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    lrr) a
    x Set a
    lrr Set a
    r)
                       (Set a
    _, Set a
    _) -> [Char] -> Set a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Failure in Data.Set.balanceL"
                  | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    x Set a
    l Set a
    r
    {-# NOINLINE balanceL #-}

    -- balanceR is called when right subtree might have been inserted to or when
    -- left subtree might have been deleted from.
    balanceR :: a -> Set a -> Set a -> Set a
    balanceR :: forall a. a -> Set a -> Set a -> Set a
    balanceR a
    x Set a
    l Set a
    r = case Set a
    l of
      Set a
    Tip -> case Set a
    r of
               Set a
    Tip -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
               (Bin Size
    _ a
    _ Set a
    Tip Set a
    Tip) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    2 a
    x Set a
    forall a. Set a
    Tip Set a
    r
               (Bin Size
    _ a
    rx Set a
    Tip rr :: Set a
    rr@(Bin Size
    _ a
    _ Set a
    _ Set a
    _)) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    3 a
    rx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) Set a
    rr
               (Bin Size
    _ a
    rx (Bin Size
    _ a
    rlx Set a
    _ Set a
    _) Set a
    Tip) -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    3 a
    rlx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin Size
    1 a
    rx Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Size
    rs a
    rx rl :: Set a
    rl@(Bin Size
    rls a
    rlx Set a
    rll Set a
    rlr) rr :: Set a
    rr@(Bin Size
    rrs a
    _ Set a
    _ Set a
    _))
                 | Size
    rls Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    ratioSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    rrs -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    rx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rls) a
    x Set a
    forall a. Set a
    Tip Set a
    rl) Set a
    rr
                 | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    rlx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    rll) a
    x Set a
    forall a. Set a
    Tip Set a
    rll) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rrsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    rlr) a
    rx Set a
    rlr Set a
    rr)

      (Bin Size
    ls a
    _ Set a
    _ Set a
    _) -> case Set a
    r of
               Set a
    Tip -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    ls) a
    x Set a
    l Set a
    forall a. Set a
    Tip

               (Bin Size
    rs a
    rx Set a
    rl Set a
    rr)
                  | Size
    rs Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    > Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    ls  -> case (Set a
    rl, Set a
    rr) of
                       (Bin Size
    rls a
    rlx Set a
    rll Set a
    rlr, Bin Size
    rrs a
    _ Set a
    _ Set a
    _)
                         | Size
    rls Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    < Size
    ratioSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Size
    rrs -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    rx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rls) a
    x Set a
    l Set a
    rl) Set a
    rr
                         | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    rlx (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    rll) a
    x Set a
    l Set a
    rll) (Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rrsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Set a -> Size
    forall a. Set a -> Size
    size Set a
    rlr) a
    rx Set a
    rlr Set a
    rr)
                       (Set a
    _, Set a
    _) -> [Char] -> Set a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Failure in Data.Set.balanceR"
                  | Bool
    otherwise -> Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Size
    1Size -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    lsSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    rs) a
    x Set a
    l Set a
    r
    {-# NOINLINE balanceR #-}

    {--------------------------------------------------------------------
      The bin constructor maintains the size of the tree
    --------------------------------------------------------------------}
    bin :: a -> Set a -> Set a -> Set a
    bin :: forall a. a -> Set a -> Set a -> Set a
    bin a
    x Set a
    l Set a
    r
      = Size -> a -> Set a -> Set a -> Set a
    forall a. Size -> a -> Set a -> Set a -> Set a
    Bin (Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    r Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Size
    1) a
    x Set a
    l Set a
    r
    {-# INLINE bin #-}

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

    -- | \(O(1)\).  Decompose a set into pieces based on the structure of the underlying
    -- tree.  This function is useful for consuming a set 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 subset less than all
    -- elements in the second, and so on).
    --
    -- Examples:
    --
    -- > splitRoot (fromList [1..6]) ==
    -- >   [fromList [1,2,3],fromList [4],fromList [5,6]]
    --
    -- > splitRoot empty == []
    --
    --  Note that the current implementation does not return more than three subsets,
    --  but you should not depend on this behaviour because it can change in the
    --  future without notice.
    --
    -- @since 0.5.4
    splitRoot :: Set a -> [Set a]
    splitRoot :: forall a. Set a -> [Set a]
    splitRoot Set a
    orig =
      case Set a
    orig of
        Set a
    Tip           -> []
        Bin Size
    _ a
    v Set a
    l Set a
    r -> [Set a
    l, a -> Set a
    forall a. a -> Set a
    singleton a
    v, Set a
    r]
    {-# INLINE splitRoot #-}

    -- | \(O(2^n \log n)\). Calculate the power set of a set: the set of all its subsets.
    --
    -- @
    -- t ``member`` powerSet s == t ``isSubsetOf`` s
    -- @
    --
    -- Example:
    --
    -- @
    -- powerSet (fromList [1,2,3]) =
    --   fromList $ map fromList [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
    -- @
    --
    -- @since 0.5.11

    -- Proof of complexity: step executes n times. At the ith step,
    -- "insertMin x `mapMonotonic` pxs" takes O(2^i log i) time since pxs has size
    -- 2^i - 1 and we insertMin into its elements which are sets of size <= i.
    -- "insertMin (singleton x)" and "`glue` pxs" are cheaper operations that both
    -- take O(i) time. Over n steps, we have a total cost of
    --
    --   O(\sum_{i=1}^{n-1} 2^i log i)
    -- = O(log n * \sum_{i=1}^{n-1} 2^i)
    -- = O(2^n log n)

    powerSet :: Set a -> Set (Set a)
    powerSet :: forall a. Set a -> Set (Set a)
    powerSet Set a
    xs0 = Set a -> Set (Set a) -> Set (Set a)
    forall a. a -> Set a -> Set a
    insertMin Set a
    forall a. Set a
    empty ((a -> Set (Set a) -> Set (Set a))
    -> Set (Set a) -> Set a -> Set (Set a)
    forall a b. (a -> b -> b) -> b -> Set a -> b
    foldr' a -> Set (Set a) -> Set (Set a)
    forall {a}. a -> Set (Set a) -> Set (Set a)
    step Set (Set a)
    forall a. Set a
    Tip Set a
    xs0) where
      step :: a -> Set (Set a) -> Set (Set a)
    step a
    x Set (Set a)
    pxs = Set a -> Set (Set a) -> Set (Set a)
    forall a. a -> Set a -> Set a
    insertMin (a -> Set a
    forall a. a -> Set a
    singleton a
    x) (a -> Set a -> Set a
    forall a. a -> Set a -> Set a
    insertMin a
    x (Set a -> Set a) -> Set (Set a) -> Set (Set a)
    forall a b. (a -> b) -> Set a -> Set b
    `mapMonotonic` Set (Set a)
    pxs) Set (Set a) -> Set (Set a) -> Set (Set a)
    forall a. Set a -> Set a -> Set a
    `glue` Set (Set a)
    pxs

    -- | \(O(nm)\). Calculate the Cartesian product of two sets.
    --
    -- @
    -- cartesianProduct xs ys = fromList $ liftA2 (,) (toList xs) (toList ys)
    -- @
    --
    -- Example:
    --
    -- @
    -- cartesianProduct (fromList [1,2]) (fromList [\'a\',\'b\']) =
    --   fromList [(1,\'a\'), (1,\'b\'), (2,\'a\'), (2,\'b\')]
    -- @
    --
    -- @since 0.5.11
    cartesianProduct :: Set a -> Set b -> Set (a, b)
    -- The obvious big-O optimal (O(nm)) implementation would be
    --
    --   cartesianProduct _as Tip = Tip
    --   cartesianProduct as bs = fromDistinctAscList
    --     [(a,b) | a <- toList as, b <- toList bs]
    --
    -- Unfortunately, this is much slower in practice, at least when the sets are
    -- constructed from ascending lists. I tried doing the same thing using a
    -- known-length (perfect balancing) variant of fromDistinctAscList, but it
    -- still didn't come close to the performance of the implementation we use in my
    -- very informal tests.
    --
    -- The implementation we use (slightly modified from one that Edward Kmett
    -- hacked together) is also optimal but performs better in practice. We map
    -- each element a in as to a set made up of (a,b) for every element b in bs,
    -- taking O(nm) overall. Then we merge these sets up the tree of as, which takes
    -- O(n log m). A brief sketch of proof for the latter:
    --
    -- Consider all nodes in the tree at the same distance from the root to be at
    -- the same "level". The nodes farthest from the root are at level 0, with
    -- levels increasing by 1 towards the root. Being a balanced tree, there are
    -- O(n/2^i) nodes at level i. At every node at level i, we merge the merged left
    -- set, current set, and merged right set into a set of size O(2^i*m) in
    -- O(log (2^i*m)) = O(i + log m) time. Over all levels, we do a total work of
    --
    --   O(\sum_{i=0}^{root_level} n * (i + log m) / 2^i)
    -- = O(  \sum_{i=0}^{root_level} n * i / 2^i
    --     + \sum_{i=0}^{root_level} n * log m / 2^i)
    -- = O(  n * \sum_{i=0}^{root_level} i/2^i
    --     + n * log m * \sum_{i=0}^{root_level} 1/2^i)
    -- = O(  n * \sum_{i=0}^{inf} i/2^i
    --     + n * log m * \sum_{i=0}^{inf} 1/2^i)
    --
    -- The sum terms converge, and we get O(n log m).

    -- When the second argument has at most one element, we can be a little
    -- clever.
    cartesianProduct :: forall a b. Set a -> Set b -> Set (a, b)
    cartesianProduct !Set a
    _as Set b
    Tip = Set (a, b)
    forall a. Set a
    Tip
    cartesianProduct Set a
    as (Bin Size
    1 b
    b Set b
    _ Set b
    _) = (a -> (a, b)) -> Set a -> Set (a, b)
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic ((a -> b -> (a, b)) -> b -> a -> (a, b)
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (,) b
    b) Set a
    as
    cartesianProduct Set a
    as Set b
    bs =
      MergeSet (a, b) -> Set (a, b)
    forall a. MergeSet a -> Set a
    getMergeSet (MergeSet (a, b) -> Set (a, b)) -> MergeSet (a, b) -> Set (a, b)
    forall a b. (a -> b) -> a -> b
    $ (a -> MergeSet (a, b)) -> Set a -> MergeSet (a, b)
    forall m a. Monoid m => (a -> m) -> Set a -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap (\a
    a -> Set (a, b) -> MergeSet (a, b)
    forall a. Set a -> MergeSet a
    MergeSet (Set (a, b) -> MergeSet (a, b)) -> Set (a, b) -> MergeSet (a, b)
    forall a b. (a -> b) -> a -> b
    $ (b -> (a, b)) -> Set b -> Set (a, b)
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic ((,) a
    a) Set b
    bs) Set a
    as

    -- A version of Set with peculiar Semigroup and Monoid instances.
    -- The result of xs <> ys will only be a valid set if the greatest
    -- element of xs is strictly less than the least element of ys.
    -- This is used to define cartesianProduct.
    newtype MergeSet a = MergeSet { forall a. MergeSet a -> Set a
    getMergeSet :: Set a }

    instance Semigroup (MergeSet a) where
      MergeSet Set a
    xs <> :: MergeSet a -> MergeSet a -> MergeSet a
    <> MergeSet Set a
    ys = Set a -> MergeSet a
    forall a. Set a -> MergeSet a
    MergeSet (Set a -> Set a -> Set a
    forall a. Set a -> Set a -> Set a
    merge Set a
    xs Set a
    ys)

    instance Monoid (MergeSet a) where
      mempty :: MergeSet a
    mempty = Set a -> MergeSet a
    forall a. Set a -> MergeSet a
    MergeSet Set a
    forall a. Set a
    empty

      mappend :: MergeSet a -> MergeSet a -> MergeSet a
    mappend = MergeSet a -> MergeSet a -> MergeSet a
    forall a. Semigroup a => a -> a -> a
    (<>)

    -- | \(O(n+m)\). Calculate the disjoint union of two sets.
    --
    -- @ disjointUnion xs ys = map Left xs ``union`` map Right ys @
    --
    -- Example:
    --
    -- @
    -- disjointUnion (fromList [1,2]) (fromList ["hi", "bye"]) =
    --   fromList [Left 1, Left 2, Right "hi", Right "bye"]
    -- @
    --
    -- @since 0.5.11
    disjointUnion :: Set a -> Set b -> Set (Either a b)
    disjointUnion :: forall a b. Set a -> Set b -> Set (Either a b)
    disjointUnion Set a
    as Set b
    bs = Set (Either a b) -> Set (Either a b) -> Set (Either a b)
    forall a. Set a -> Set a -> Set a
    merge ((a -> Either a b) -> Set a -> Set (Either a b)
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic a -> Either a b
    forall a b. a -> Either a b
    Left Set a
    as) ((b -> Either a b) -> Set b -> Set (Either a b)
    forall a b. (a -> b) -> Set a -> Set b
    mapMonotonic b -> Either a b
    forall a b. b -> Either a b
    Right Set b
    bs)

    {--------------------------------------------------------------------
      Debugging
    --------------------------------------------------------------------}
    -- | \(O(n \log n)\). Show the tree that implements the set. The tree is shown
    -- in a compressed, hanging format.
    showTree :: Show a => Set a -> String
    showTree :: forall a. Show a => Set a -> [Char]
    showTree Set a
    s
      = Bool -> Bool -> Set a -> [Char]
    forall a. Show a => Bool -> Bool -> Set a -> [Char]
    showTreeWith Bool
    True Bool
    False Set a
    s

    {- | \(O(n \log n)\). The expression (@showTreeWith hang wide map@) shows
     the tree that implements the set. 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.

    > Set> putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]
    > 4
    > +--2
    > |  +--1
    > |  +--3
    > +--5
    >
    > Set> putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]
    > 4
    > |
    > +--2
    > |  |
    > |  +--1
    > |  |
    > |  +--3
    > |
    > +--5
    >
    > Set> putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]
    > +--5
    > |
    > 4
    > |
    > |  +--3
    > |  |
    > +--2
    >    |
    >    +--1

    -}
    showTreeWith :: Show a => Bool -> Bool -> Set a -> String
    showTreeWith :: forall a. Show a => Bool -> Bool -> Set a -> [Char]
    showTreeWith Bool
    hang Bool
    wide Set a
    t
      | Bool
    hang      = (Bool -> [[Char]] -> Set a -> ShowS
    forall a. Show a => Bool -> [[Char]] -> Set a -> ShowS
    showsTreeHang Bool
    wide [] Set a
    t) [Char]
    ""
      | Bool
    otherwise = (Bool -> [[Char]] -> [[Char]] -> Set a -> ShowS
    forall a. Show a => Bool -> [[Char]] -> [[Char]] -> Set a -> ShowS
    showsTree Bool
    wide [] [] Set a
    t) [Char]
    ""

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

    showsTreeHang :: Show a => Bool -> [String] -> Set a -> ShowS
    showsTreeHang :: forall a. Show a => Bool -> [[Char]] -> Set a -> ShowS
    showsTreeHang Bool
    wide [[Char]]
    bars Set a
    t
      = case Set a
    t of
          Set a
    Tip -> [[Char]] -> ShowS
    showsBars [[Char]]
    bars ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "|\n"
          Bin Size
    _ a
    x Set a
    Tip Set a
    Tip
              -> [[Char]] -> ShowS
    showsBars [[Char]]
    bars ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ShowS
    forall a. Show a => a -> ShowS
    shows a
    x ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n"
          Bin Size
    _ a
    x Set a
    l Set a
    r
              -> [[Char]] -> ShowS
    showsBars [[Char]]
    bars ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ShowS
    forall a. Show a => a -> ShowS
    shows a
    x ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> ShowS
    showString [Char]
    "\n" ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                 Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    bars ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                 Bool -> [[Char]] -> Set a -> ShowS
    forall a. Show a => Bool -> [[Char]] -> Set a -> ShowS
    showsTreeHang Bool
    wide ([[Char]] -> [[Char]]
    withBar [[Char]]
    bars) Set a
    l ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                 Bool -> [[Char]] -> ShowS
    showWide Bool
    wide [[Char]]
    bars ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                 Bool -> [[Char]] -> Set a -> ShowS
    forall a. Show a => Bool -> [[Char]] -> Set a -> ShowS
    showsTreeHang Bool
    wide ([[Char]] -> [[Char]]
    withEmpty [[Char]]
    bars) Set a
    r

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

    showsBars :: [String] -> ShowS
    showsBars :: [[Char]] -> ShowS
    showsBars [[Char]]
    bars
      = case [[Char]]
    bars of
          [] -> ShowS
    forall a. a -> a
    id
          [Char]
    _ : [[Char]]
    tl -> [Char] -> ShowS
    showString ([[Char]] -> [Char]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Char]] -> [[Char]]
    forall a. [a] -> [a]
    reverse [[Char]]
    tl)) ShowS -> ShowS -> ShowS
    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]
    "|  "[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    bars
    withEmpty :: [[Char]] -> [[Char]]
    withEmpty [[Char]]
    bars = [Char]
    "   "[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    bars

    {--------------------------------------------------------------------
      Assertions
    --------------------------------------------------------------------}
    -- | \(O(n)\). Test if the internal set structure is valid.
    valid :: Ord a => Set a -> Bool
    valid :: forall a. Ord a => Set a -> Bool
    valid Set a
    t
      = Set a -> Bool
    forall a. Set a -> Bool
    balanced Set a
    t Bool -> Bool -> Bool
    && Set a -> Bool
    forall a. Ord a => Set a -> Bool
    ordered Set a
    t Bool -> Bool -> Bool
    && Set a -> Bool
    forall a. Set a -> Bool
    validsize Set a
    t

    ordered :: Ord a => Set a -> Bool
    ordered :: forall a. Ord a => Set a -> Bool
    ordered Set a
    t
      = (a -> Bool) -> (a -> Bool) -> Set a -> Bool
    forall {t}. Ord t => (t -> Bool) -> (t -> Bool) -> Set t -> Bool
    bounded (Bool -> a -> Bool
    forall a b. a -> b -> a
    const Bool
    True) (Bool -> a -> Bool
    forall a b. a -> b -> a
    const Bool
    True) Set a
    t
      where
        bounded :: (t -> Bool) -> (t -> Bool) -> Set t -> Bool
    bounded t -> Bool
    lo t -> Bool
    hi Set t
    t'
          = case Set t
    t' of
              Set t
    Tip         -> Bool
    True
              Bin Size
    _ t
    x Set t
    l Set t
    r -> (t -> Bool
    lo t
    x) Bool -> Bool -> Bool
    && (t -> Bool
    hi t
    x) Bool -> Bool -> Bool
    && (t -> Bool) -> (t -> Bool) -> Set t -> Bool
    bounded t -> Bool
    lo (t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    <t
    x) Set t
    l Bool -> Bool -> Bool
    && (t -> Bool) -> (t -> Bool) -> Set t -> Bool
    bounded (t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    >t
    x) t -> Bool
    hi Set t
    r

    balanced :: Set a -> Bool
    balanced :: forall a. Set a -> Bool
    balanced Set a
    t
      = case Set a
    t of
          Set a
    Tip         -> Bool
    True
          Bin Size
    _ a
    _ Set a
    l Set a
    r -> (Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Size
    forall a. Num a => a -> a -> a
    + Set a -> Size
    forall a. Set a -> Size
    size Set a
    r Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    1 Bool -> Bool -> Bool
    || (Set a -> Size
    forall a. Set a -> Size
    size Set a
    l Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Set a -> Size
    forall a. Set a -> Size
    size Set a
    r Bool -> Bool -> Bool
    && Set a -> Size
    forall a. Set a -> Size
    size Set a
    r Size -> Size -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Size
    deltaSize -> Size -> Size
    forall a. Num a => a -> a -> a
    *Set a -> Size
    forall a. Set a -> Size
    size Set a
    l)) Bool -> Bool -> Bool
    &&
                         Set a -> Bool
    forall a. Set a -> Bool
    balanced Set a
    l Bool -> Bool -> Bool
    && Set a -> Bool
    forall a. Set a -> Bool
    balanced Set a
    r

    validsize :: Set a -> Bool
    validsize :: forall a. Set a -> Bool
    validsize Set a
    t
      = (Set a -> Maybe Size
    forall {a}. Set a -> Maybe Size
    realsize Set a
    t Maybe Size -> Maybe Size -> Bool
    forall a. Eq a => a -> a -> Bool
    == Size -> Maybe Size
    forall a. a -> Maybe a
    Just (Set a -> Size
    forall a. Set a -> Size
    size Set a
    t))
      where
        realsize :: Set a -> Maybe Size
    realsize Set a
    t'
          = case Set a
    t' of
              Set a
    Tip          -> Size -> Maybe Size
    forall a. a -> Maybe a
    Just Size
    0
              Bin Size
    sz a
    _ Set a
    l Set a
    r -> case (Set a -> Maybe Size
    realsize Set a
    l,Set a -> Maybe Size
    realsize Set a
    r) of
                                (Just Size
    n,Just Size
    m)  | Size
    nSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    mSize -> Size -> Size
    forall a. Num a => a -> a -> a
    +Size
    1 Size -> Size -> Bool
    forall a. Eq a => a -> a -> Bool
    == Size
    sz  -> Size -> Maybe Size
    forall a. a -> Maybe a
    Just Size
    sz
                                (Maybe Size, Maybe Size)
    _                -> Maybe Size
    forall a. Maybe a
    Nothing