    {-# LANGUAGE CPP #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE PatternGuards #-}
    #if __GLASGOW_HASKELL__
    {-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
    #endif
    #if !defined(TESTING) && defined(__GLASGOW_HASKELL__)
    {-# LANGUAGE Trustworthy #-}
    #endif
    #if __GLASGOW_HASKELL__ >= 708
    {-# LANGUAGE RoleAnnotations #-}
    {-# 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,Typeable
                , 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
                , cartesianProduct
                , disjointUnion

                -- * 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 Prelude hiding (filter,foldl,foldr,null,map,take,drop,splitAt)
    import Control.Applicative (Const(..))
    import qualified Data.List as List
    import Data.Bits (shiftL, shiftR)
    #if !MIN_VERSION_base(4,8,0)
    import Data.Monoid (Monoid(..))
    #endif
    #if MIN_VERSION_base(4,9,0)
    import Data.Semigroup (Semigroup(stimes))
    #endif
    #if !(MIN_VERSION_base(4,11,0)) && MIN_VERSION_base(4,9,0)
    import Data.Semigroup (Semigroup((<>)))
    #endif
    #if MIN_VERSION_base(4,9,0)
    import Data.Semigroup (stimesIdempotentMonoid)
    import Data.Functor.Classes
    #endif
    #if MIN_VERSION_base(4,8,0)
    import Data.Functor.Identity (Identity)
    #endif
    import qualified Data.Foldable as Foldable
    #if !MIN_VERSION_base(4,8,0)
    import Data.Foldable (Foldable (foldMap))
    #endif
    import Data.Typeable
    import Control.DeepSeq (NFData(rnf))

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

    #if __GLASGOW_HASKELL__
    import GHC.Exts ( build, lazy )
    #if __GLASGOW_HASKELL__ >= 708
    import qualified GHC.Exts as GHCExts
    #endif
    import Text.Read ( readPrec, Read (..), Lexeme (..), parens, prec
                     , lexP, readListPrecDefault )
    import Data.Data
    #endif

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

    -- | /O(m*log(n\/m+1)), m <= 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

    #if __GLASGOW_HASKELL__ >= 708
    type role Set nominal
    #endif

    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
    #if !(MIN_VERSION_base(4,9,0))
        mappend = union
    #else
        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
    #endif

    -- | 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 Int
    1 a
    k Set a
    _ Set a
    _) = a
    k
                go (Bin Int
    _ 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 Int
    1 a
    k Set a
    _ Set a
    _) = a -> m
    f a
    k
                go (Bin Int
    _ 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' #-}
    #if MIN_VERSION_base(4,8,0)
        length :: forall a. Set a -> Int
    length = Set a -> Int
    forall a. Set a -> Int
    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 Int
    _ 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 #-}
    #endif

    #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 -> Int
    constrIndex Constr
    c of
        Int
    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)
        Int
    _ -> [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 -> Int
    size Set a
    Tip = Int
    0
    size (Bin Int
    sz a
    _ Set a
    _ Set a
    _) = Int
    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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 = Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 Int
    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
    `seq` (a
    orig a -> a -> Bool
    forall a. a -> a -> Bool
    `ptrEq` a
    y) -> Set a
    t
               | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 Int
    _ 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 Int
    _ 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 (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

    #if MIN_VERSION_base(4,8,0)
    {-# SPECIALIZE alterF :: Ord a => (Bool -> Identity Bool) -> a -> Set a -> Identity (Set a) #-}
    #endif

    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 Int
    _ 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(m*log(n\/m + 1)), m <= 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 -> Int
    forall a. Set a -> Int
    size Set a
    s1 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Set a -> Int
    forall a. Set a -> Int
    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(m*log(n\/m + 1)), m <= 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 -> Int
    forall a. Set a -> Int
    size Set a
    t1 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Int
    forall a. Set a -> Int
    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 accound 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 Int
    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 Int
    _ 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 -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Int
    forall a. Set a -> Int
    size Set a
    lt Bool -> Bool -> Bool
    && Set a -> Int
    forall a. Set a -> Int
    size Set a
    r Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Set a -> Int
    forall a. Set a -> Int
    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(m*log(n\/m + 1)), m <= 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 Int
    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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ a
    _ Set a
    Tip Set a
    r) = Set a
    r
    deleteMin (Bin Int
    _ 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 Int
    _ a
    _ Set a
    l Set a
    Tip) = Set a
    l
    deleteMax (Bin Int
    _ 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 (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(m*log(n\/m + 1)), m <= 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 Int
    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 Int
    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 Int
    _ 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(m*log(n\/m + 1)), m <= 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 Int
    _ 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 -> Int
    forall a. Set a -> Int
    size Set a
    l1l2 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    size Set a
    r1r2 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> Int
    forall a. Set a -> Int
    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(m*log(n\/m + 1)), m <= 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 Int
    _ 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

    {--------------------------------------------------------------------
      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 Int
    _ 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 Int
    _ 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 Int
    sz a
    x Set a
    l Set a
    r) = Int -> b -> Set b -> Set b -> Set b
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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
    --------------------------------------------------------------------}
    #if __GLASGOW_HASKELL__ >= 708
    -- | @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 = [Item (Set a)] -> Set a
    forall a. Ord a => [a] -> Set a
    fromList
      toList :: Set a -> [Item (Set a)]
    toList   = 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] = Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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' (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x0 Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) [a]
    xs0
                        | Bool
    otherwise = Int -> Set a -> [a] -> Set a
    forall {a} {t}.
    (Ord a, Num t, Bits t) =>
    t -> Set a -> [a] -> Set a
    go (Int
    1::Int) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 (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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    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 (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip, [], [a]
    xss)
                                          else (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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) = Int -> Set a -> [a] -> Set a
    forall {t} {a}. (Num t, Bits t) => t -> Set a -> [a] -> Set a
    go (Int
    1::Int) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    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 = (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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) = Int -> Set a -> [a] -> Set a
    forall {t} {a}. (Num t, Bits t) => t -> Set a -> [a] -> Set a
    go (Int
    1::Int) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    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 = (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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 -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    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 -> Int
    forall a. Set a -> Int
    size Set a
    t1 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set a -> Int
    forall a. Set a -> Int
    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 :: Int -> Set a -> ShowS
    showsPrec Int
    p Set a
    xs = Bool -> ShowS -> ShowS
    showParen (Int
    p Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    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)

    #if MIN_VERSION_base(4,9,0)
    -- | @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 -> Int
    forall a. Set a -> Int
    size Set a
    m Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Set b -> Int
    forall a. Set a -> Int
    size Set b
    n Bool -> Bool -> Bool
    && (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 (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.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Set a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl Int
    d Set a
    m =
            (Int -> [a] -> ShowS) -> [Char] -> Int -> [a] -> ShowS
    forall a. (Int -> a -> ShowS) -> [Char] -> Int -> a -> ShowS
    showsUnaryWith ((Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> [a] -> ShowS
    forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl) [Char]
    "fromList" Int
    d (Set a -> [a]
    forall a. Set a -> [a]
    toList Set a
    m)
    #endif

    {--------------------------------------------------------------------
      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
    $ Int -> ReadPrec (Set a) -> ReadPrec (Set a)
    forall a. Int -> ReadPrec a -> ReadPrec a
    prec Int
    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 (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

    {--------------------------------------------------------------------
      Typeable/Data
    --------------------------------------------------------------------}

    INSTANCE_TYPEABLE1(Set)

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

    instance NFData a => NFData (Set a) where
        rnf :: Set a -> ()
    rnf Set a
    Tip           = ()
        rnf (Bin Int
    _ a
    y Set a
    l Set a
    r) = a -> ()
    forall a. NFData a => a -> ()
    rnf a
    y () -> () -> ()
    `seq` Set a -> ()
    forall a. NFData a => a -> ()
    rnf Set a
    l () -> () -> ()
    `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 Int
    _ 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 Int
    _ 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 -> Int
    findIndex = Int -> a -> Set a -> Int
    forall a. Ord a => Int -> a -> Set a -> Int
    go Int
    0
      where
        go :: Ord a => Int -> a -> Set a -> Int
        go :: forall a. Ord a => Int -> a -> Set a -> Int
    go !Int
    _ !a
    _ Set a
    Tip  = [Char] -> Int
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.findIndex: element is not in the set"
        go Int
    idx a
    x (Bin Int
    _ 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 -> Int -> a -> Set a -> Int
    forall a. Ord a => Int -> a -> Set a -> Int
    go Int
    idx a
    x Set a
    l
          Ordering
    GT -> Int -> a -> Set a -> Int
    forall a. Ord a => Int -> a -> Set a -> Int
    go (Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) a
    x Set a
    r
          Ordering
    EQ -> Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    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 Int
    lookupIndex = Int -> a -> Set a -> Maybe Int
    forall a. Ord a => Int -> a -> Set a -> Maybe Int
    go Int
    0
      where
        go :: Ord a => Int -> a -> Set a -> Maybe Int
        go :: forall a. Ord a => Int -> a -> Set a -> Maybe Int
    go !Int
    _ !a
    _ Set a
    Tip  = Maybe Int
    forall a. Maybe a
    Nothing
        go Int
    idx a
    x (Bin Int
    _ 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 -> Int -> a -> Set a -> Maybe Int
    forall a. Ord a => Int -> a -> Set a -> Maybe Int
    go Int
    idx a
    x Set a
    l
          Ordering
    GT -> Int -> a -> Set a -> Maybe Int
    forall a. Ord a => Int -> a -> Set a -> Maybe Int
    go (Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) a
    x Set a
    r
          Ordering
    EQ -> Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $! Int
    idx Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    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. Int -> Set a -> a
    elemAt !Int
    _ Set a
    Tip = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Set.elemAt: index out of range"
    elemAt Int
    i (Bin Int
    _ a
    x Set a
    l Set a
    r)
      = case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    i Int
    sizeL of
          Ordering
    LT -> Int -> Set a -> a
    forall a. Int -> Set a -> a
    elemAt Int
    i Set a
    l
          Ordering
    GT -> Int -> Set a -> a
    forall a. Int -> Set a -> a
    elemAt (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    sizeLInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) Set a
    r
          Ordering
    EQ -> a
    x
      where
        sizeL :: Int
    sizeL = Set a -> Int
    forall a. Set a -> Int
    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. Int -> Set a -> Set a
    deleteAt !Int
    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 Int
    _ a
    x Set a
    l Set a
    r -> case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    i Int
    sizeL of
          Ordering
    LT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    balanceR a
    x (Int -> Set a -> Set a
    forall a. Int -> Set a -> Set a
    deleteAt Int
    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 (Int -> Set a -> Set a
    forall a. Int -> Set a -> Set a
    deleteAt (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    sizeLInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    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 :: Int
    sizeL = Set a -> Int
    forall a. Set a -> Int
    size Set a
    l

    -- | 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. Int -> Set a -> Set a
    take Int
    i Set a
    m | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Int
    forall a. Set a -> Int
    size Set a
    m = Set a
    m
    take Int
    i0 Set a
    m0 = Int -> Set a -> Set a
    forall a. Int -> Set a -> Set a
    go Int
    i0 Set a
    m0
      where
        go :: Int -> Set a -> Set a
    go Int
    i !Set a
    _ | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    0 = Set a
    forall a. Set a
    Tip
        go !Int
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
        go Int
    i (Bin Int
    _ a
    x Set a
    l Set a
    r) =
          case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    i Int
    sizeL of
            Ordering
    LT -> Int -> Set a -> Set a
    go Int
    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 (Int -> Set a -> Set a
    go (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    sizeL Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) Set a
    r)
            Ordering
    EQ -> Set a
    l
          where sizeL :: Int
    sizeL = Set a -> Int
    forall a. Set a -> Int
    size Set a
    l

    -- | 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. Int -> Set a -> Set a
    drop Int
    i Set a
    m | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Int
    forall a. Set a -> Int
    size Set a
    m = Set a
    forall a. Set a
    Tip
    drop Int
    i0 Set a
    m0 = Int -> Set a -> Set a
    forall a. Int -> Set a -> Set a
    go Int
    i0 Set a
    m0
      where
        go :: Int -> Set a -> Set a
    go Int
    i Set a
    m | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    0 = Set a
    m
        go !Int
    _ Set a
    Tip = Set a
    forall a. Set a
    Tip
        go Int
    i (Bin Int
    _ a
    x Set a
    l Set a
    r) =
          case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    i Int
    sizeL of
            Ordering
    LT -> a -> Set a -> Set a -> Set a
    forall a. a -> Set a -> Set a -> Set a
    link a
    x (Int -> Set a -> Set a
    go Int
    i Set a
    l) Set a
    r
            Ordering
    GT -> Int -> Set a -> Set a
    go (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    sizeL Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    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 :: Int
    sizeL = Set a -> Int
    forall a. Set a -> Int
    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. Int -> Set a -> (Set a, Set a)
    splitAt Int
    i0 Set a
    m0
      | Int
    i0 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Set a -> Int
    forall a. Set a -> Int
    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
    $ Int -> Set a -> StrictPair (Set a) (Set a)
    forall {a}. Int -> Set a -> StrictPair (Set a) (Set a)
    go Int
    i0 Set a
    m0
      where
        go :: Int -> Set a -> StrictPair (Set a) (Set a)
    go Int
    i Set a
    m | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    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 !Int
    _ 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 Int
    i (Bin Int
    _ a
    x Set a
    l Set a
    r)
          = case Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Int
    i Int
    sizeL of
              Ordering
    LT -> case Int -> Set a -> StrictPair (Set a) (Set a)
    go Int
    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 Int -> Set a -> StrictPair (Set a) (Set a)
    go (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    sizeL Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    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 :: Int
    sizeL = Set a -> Int
    forall a. Set a -> Int
    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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    sizeL a
    y Set a
    ly Set a
    ry) r :: Set a
    r@(Bin Int
    sizeR a
    z Set a
    lz Set a
    rz)
      | Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    sizeL Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    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
      | Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    sizeR Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    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 Int
    _ 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 Int
    _ 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 Int
    sizeL a
    x Set a
    lx Set a
    rx) r :: Set a
    r@(Bin Int
    sizeR a
    y Set a
    ly Set a
    ry)
      | Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    sizeL Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    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
      | Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    sizeR Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    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 Int
    sl a
    xl Set a
    ll Set a
    lr) r :: Set a
    r@(Bin Int
    sr a
    xr Set a
    rl Set a
    rr)
      | Int
    sl Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 correspondes 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 errorneous:
      - 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 :: Int
    delta = Int
    3
    ratio :: Int
    ratio = Int
    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 -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
               (Bin Int
    _ a
    _ Set a
    Tip Set a
    Tip) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    2 a
    x Set a
    l Set a
    forall a. Set a
    Tip
               (Bin Int
    _ a
    lx Set a
    Tip (Bin Int
    _ a
    lrx Set a
    _ Set a
    _)) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    3 a
    lrx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    lx Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Int
    _ a
    lx ll :: Set a
    ll@(Bin Int
    _ a
    _ Set a
    _ Set a
    _) Set a
    Tip) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    3 a
    lx Set a
    ll (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Int
    ls a
    lx ll :: Set a
    ll@(Bin Int
    lls a
    _ Set a
    _ Set a
    _) lr :: Set a
    lr@(Bin Int
    lrs a
    lrx Set a
    lrl Set a
    lrr))
                 | Int
    lrs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    ratioInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    lls -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    ls) a
    lx Set a
    ll (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lrs) a
    x Set a
    lr Set a
    forall a. Set a
    Tip)
                 | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    ls) a
    lrx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    llsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    lrl) a
    lx Set a
    ll Set a
    lrl) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    lrr) a
    x Set a
    lrr Set a
    forall a. Set a
    Tip)

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

               (Bin Int
    ls a
    lx Set a
    ll Set a
    lr)
                  | Int
    ls Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    rs  -> case (Set a
    ll, Set a
    lr) of
                       (Bin Int
    lls a
    _ Set a
    _ Set a
    _, Bin Int
    lrs a
    lrx Set a
    lrl Set a
    lrr)
                         | Int
    lrs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    ratioInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    lls -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    lx Set a
    ll (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lrs) a
    x Set a
    lr Set a
    r)
                         | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    lrx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    llsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    lrl) a
    lx Set a
    ll Set a
    lrl) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    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.Map.balanceL"
                  | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    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 -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip
               (Bin Int
    _ a
    _ Set a
    Tip Set a
    Tip) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    2 a
    x Set a
    forall a. Set a
    Tip Set a
    r
               (Bin Int
    _ a
    rx Set a
    Tip rr :: Set a
    rr@(Bin Int
    _ a
    _ Set a
    _ Set a
    _)) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    3 a
    rx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) Set a
    rr
               (Bin Int
    _ a
    rx (Bin Int
    _ a
    rlx Set a
    _ Set a
    _) Set a
    Tip) -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    3 a
    rlx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    x Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin Int
    1 a
    rx Set a
    forall a. Set a
    Tip Set a
    forall a. Set a
    Tip)
               (Bin Int
    rs a
    rx rl :: Set a
    rl@(Bin Int
    rls a
    rlx Set a
    rll Set a
    rlr) rr :: Set a
    rr@(Bin Int
    rrs a
    _ Set a
    _ Set a
    _))
                 | Int
    rls Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    ratioInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    rrs -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    rx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rls) a
    x Set a
    forall a. Set a
    Tip Set a
    rl) Set a
    rr
                 | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    rlx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    rll) a
    x Set a
    forall a. Set a
    Tip Set a
    rll) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rrsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    rlr) a
    rx Set a
    rlr Set a
    rr)

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

               (Bin Int
    rs a
    rx Set a
    rl Set a
    rr)
                  | Int
    rs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    ls  -> case (Set a
    rl, Set a
    rr) of
                       (Bin Int
    rls a
    rlx Set a
    rll Set a
    rlr, Bin Int
    rrs a
    _ Set a
    _ Set a
    _)
                         | Int
    rls Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    ratioInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    rrs -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    rx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rls) a
    x Set a
    l Set a
    rl) Set a
    rr
                         | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rs) a
    rlx (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    size Set a
    rll) a
    x Set a
    l Set a
    rll) (Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    rrsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Set a -> Int
    forall a. Set a -> Int
    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.Map.balanceR"
                  | Bool
    otherwise -> Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Int
    1Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    lsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    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
      = Int -> a -> Set a -> Set a -> Set a
    forall a. Int -> a -> Set a -> Set a -> Set a
    Bin (Set a -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    size Set a
    r Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    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 Int
    _ 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 #-}

    -- | 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
    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(m*n)/ (conjectured). 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)
    -- I don't know for sure if this implementation (slightly modified from one
    -- that Edward Kmett hacked together) is optimal. TODO: try to prove or
    -- refute it.
    --
    -- We could definitely get big-O optimal (O(m * n)) in a rather simple way:
    --
    --   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 Kmett's version in my very
    -- informal tests.

    -- 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 Int
    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 (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 }

    #if (MIN_VERSION_base(4,9,0))
    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)
    #endif

    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

    #if (MIN_VERSION_base(4,9,0))
      mappend :: MergeSet a -> MergeSet a -> MergeSet a
    mappend = MergeSet a -> MergeSet a -> MergeSet a
    forall a. Semigroup a => a -> a -> a
    (<>)
    #else
      mappend (MergeSet xs) (MergeSet ys) = MergeSet (merge xs ys)
    #endif

    -- | 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)/. 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)/. 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 Int
    _ 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 Int
    _ 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 Int
    _ 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 Int
    _ 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] -> ShowS
    showString ([[Char]] -> [Char]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Char]] -> [[Char]]
    forall a. [a] -> [a]
    reverse ([[Char]] -> [[Char]]
    forall a. [a] -> [a]
    tail [[Char]]
    bars))) 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 Int
    _ 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 Int
    _ a
    _ Set a
    l Set a
    r -> (Set a -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Set a -> Int
    forall a. Set a -> Int
    size Set a
    r Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    1 Bool -> Bool -> Bool
    || (Set a -> Int
    forall a. Set a -> Int
    size Set a
    l Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Set a -> Int
    forall a. Set a -> Int
    size Set a
    r Bool -> Bool -> Bool
    && Set a -> Int
    forall a. Set a -> Int
    size Set a
    r Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    deltaInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Set a -> Int
    forall a. Set a -> Int
    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 Int
    forall {a}. Set a -> Maybe Int
    realsize Set a
    t Maybe Int -> Maybe Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Set a -> Int
    forall a. Set a -> Int
    size Set a
    t))
      where
        realsize :: Set a -> Maybe Int
    realsize Set a
    t'
          = case Set a
    t' of
              Set a
    Tip          -> Int -> Maybe Int
    forall a. a -> Maybe a
    Just Int
    0
              Bin Int
    sz a
    _ Set a
    l Set a
    r -> case (Set a -> Maybe Int
    realsize Set a
    l,Set a -> Maybe Int
    realsize Set a
    r) of
                                (Just Int
    n,Just Int
    m)  | Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    mInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    sz  -> Int -> Maybe Int
    forall a. a -> Maybe a
    Just Int
    sz
                                (Maybe Int, Maybe Int)
    _                -> Maybe Int
    forall a. Maybe a
    Nothing