    {-# LANGUAGE PatternGuards #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Util.Stack
    -- Description :  Utility functions for manipulating @Maybe Stack@s.
    -- Copyright   :  Quentin Moser <moserq@gmail.com>
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  orphaned
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Utility functions for manipulating @Maybe Stack@s.
    --
    -----------------------------------------------------------------------------

    module XMonad.Util.Stack ( -- * Usage
                               -- | This is a developer-oriented module, intended to be used
                               -- for writing new extentions.
                               Zipper
                             , emptyZ
                             , singletonZ

                               -- * Conversions
                             , fromIndex
                             , toIndex
                             , fromTags
                             , toTags

                               -- * 'Zipper' manipulation functions
                               -- ** Insertion, movement
                             , insertUpZ
                             , insertDownZ
                             , swapUpZ
                             , swapDownZ
                             , swapMasterZ
                               -- ** Focus movement
                             , focusUpZ
                             , focusDownZ
                             , focusMasterZ
                             , findS
                             , findZ
                               -- ** Extraction
                             , getFocusZ
                             , getIZ
                               -- ** Sorting
                             , sortZ
                             , sortByZ
                               -- ** Maps
                             , mapZ
                             , mapZ_
                             , mapZM
                             , mapZM_
                             , onFocusedZ
                             , onFocusedZM
                             , onIndexZ
                             , onIndexZM
                               -- ** Filters
                             , filterZ
                             , filterZ_
                             , deleteFocusedZ
                             , deleteIndexZ
                               -- ** Folds
                             , foldrZ
                             , foldlZ
                             , foldrZ_
                             , foldlZ_
                             , elemZ

                               -- * Other utility functions
                             , getI
                             , tagBy
                             , fromE
                             , mapE
                             , mapE_
                             , mapEM
                             , mapEM_
                             , reverseS
                             , reverseZ
                             ) where

    import qualified XMonad.StackSet as W
    import XMonad.Prelude (guard, sortBy, (!?), (<|>))

    type Zipper a = Maybe (W.Stack a)

    emptyZ :: Zipper a
    emptyZ :: forall a. Zipper a
    emptyZ = Maybe (Stack a)
    forall a. Maybe a
    Nothing

    singletonZ :: a -> Zipper a
    singletonZ :: forall a. a -> Zipper a
    singletonZ a
    a = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    a [] []

    -- * Conversions

    -- | Create a stack from a list, and the 0-based index of the focused element.
    -- If the index is out of bounds, focus will go to the first element.
    fromIndex :: [a] -> Int -> Zipper a
    fromIndex :: forall a. [a] -> Int -> Zipper a
    fromIndex [a]
    as Int
    i = [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags ([Either a a] -> Zipper a) -> [Either a a] -> Zipper a
    forall a b. (a -> b) -> a -> b
    $ ((a -> Either a a) -> a -> Either a a)
    -> [a -> Either a a] -> [a] -> [Either a a]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (a -> Either a a) -> a -> Either a a
    forall a b. (a -> b) -> a -> b
    ($) (Int -> (a -> Either a a) -> [a -> Either a a]
    forall a. Int -> a -> [a]
    replicate Int
    i a -> Either a a
    forall a b. a -> Either a b
    Left [a -> Either a a] -> [a -> Either a a] -> [a -> Either a a]
    forall a. [a] -> [a] -> [a]
    ++ [a -> Either a a
    forall a b. b -> Either a b
    Right] [a -> Either a a] -> [a -> Either a a] -> [a -> Either a a]
    forall a. [a] -> [a] -> [a]
    ++ (a -> Either a a) -> [a -> Either a a]
    forall a. a -> [a]
    repeat a -> Either a a
    forall a b. a -> Either a b
    Left) [a]
    as

    -- | Turn a stack into a list and the index of its focused element.
    toIndex :: Zipper a -> ([a], Maybe Int)
    toIndex :: forall a. Zipper a -> ([a], Maybe Int)
    toIndex Maybe (Stack a)
    Nothing = ([], Maybe Int
    forall a. Maybe a
    Nothing)
    toIndex (Just Stack a
    s) = (Stack a -> [a]
    forall a. Stack a -> [a]
    W.integrate Stack a
    s, Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $ [a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([a] -> Int) -> [a] -> Int
    forall a b. (a -> b) -> a -> b
    $ Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s)

    -- | Create a stack from a list of 'Either'-tagged values. Focus will go to
    -- the first 'Right' value, or if there is none, to the first 'Left' one.
    fromTags :: [Either a a] -> Zipper a
    fromTags :: forall a. [Either a a] -> Zipper a
    fromTags = ([a], Maybe a, [a]) -> Maybe (Stack a)
    forall {a}. ([a], Maybe a, [a]) -> Maybe (Stack a)
    finalize (([a], Maybe a, [a]) -> Maybe (Stack a))
    -> ([Either a a] -> ([a], Maybe a, [a]))
    -> [Either a a]
    -> Maybe (Stack a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Either a a -> ([a], Maybe a, [a]) -> ([a], Maybe a, [a]))
    -> ([a], Maybe a, [a]) -> [Either a a] -> ([a], Maybe a, [a])
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Either a a -> ([a], Maybe a, [a]) -> ([a], Maybe a, [a])
    forall {a}.
    Either a a -> ([a], Maybe a, [a]) -> ([a], Maybe a, [a])
    step ([], Maybe a
    forall a. Maybe a
    Nothing, [])
        where step :: Either a a -> ([a], Maybe a, [a]) -> ([a], Maybe a, [a])
    step (Right a
    a) ([a]
    u, Just a
    f, [a]
    d) = ([], a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a, [a]
    u[a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++a
    fa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    d)
              step (Right a
    a) ([a]
    u, Maybe a
    Nothing, [a]
    d) = ([a]
    u, a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a, [a]
    d)
              step (Left a
    a) ([a]
    u, Just a
    f, [a]
    d) = (a
    aa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    u, a -> Maybe a
    forall a. a -> Maybe a
    Just a
    f, [a]
    d)
              step (Left a
    a) ([a]
    u, Maybe a
    Nothing, [a]
    d) = ([a]
    u, Maybe a
    forall a. Maybe a
    Nothing, a
    aa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    d)
              finalize :: ([a], Maybe a, [a]) -> Maybe (Stack a)
    finalize ([a]
    u, Just a
    f, [a]
    d) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    f ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    u) [a]
    d
              finalize ([a]
    u, Maybe a
    Nothing, a
    a:[a]
    d) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    a ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    u) [a]
    d
              finalize ([a]
    _, Maybe a
    Nothing, []) = Maybe (Stack a)
    forall a. Maybe a
    Nothing

    -- | Turn a stack into an 'Either'-tagged list. The focused element
    -- will be tagged with 'Right', the others with 'Left'.
    toTags :: Zipper a -> [Either a a]
    toTags :: forall a. Zipper a -> [Either a a]
    toTags Maybe (Stack a)
    Nothing = []
    toTags (Just Stack a
    s) = (a -> Either a a) -> [a] -> [Either a a]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Either a a
    forall a b. a -> Either a b
    Left ([a] -> [a]
    forall a. [a] -> [a]
    reverse ([a] -> [a]) -> (Stack a -> [a]) -> Stack a -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack a -> [a]
    forall a. Stack a -> [a]
    W.up (Stack a -> [a]) -> Stack a -> [a]
    forall a b. (a -> b) -> a -> b
    $ Stack a
    s) [Either a a] -> [Either a a] -> [Either a a]
    forall a. [a] -> [a] -> [a]
    ++ [a -> Either a a
    forall a b. b -> Either a b
    Right (a -> Either a a) -> (Stack a -> a) -> Stack a -> Either a a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack a -> a
    forall a. Stack a -> a
    W.focus (Stack a -> Either a a) -> Stack a -> Either a a
    forall a b. (a -> b) -> a -> b
    $ Stack a
    s]
                      [Either a a] -> [Either a a] -> [Either a a]
    forall a. [a] -> [a] -> [a]
    ++ (a -> Either a a) -> [a] -> [Either a a]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Either a a
    forall a b. a -> Either a b
    Left (Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s)

    -- * Zipper functions

    -- ** Insertion, movement

    -- | Insert an element before the focused one, and focus it
    insertUpZ :: a -> Zipper a -> Zipper a
    insertUpZ :: forall a. a -> Zipper a -> Zipper a
    insertUpZ a
    a Maybe (Stack a)
    Nothing = [a] -> Maybe (Stack a)
    forall a. [a] -> Maybe (Stack a)
    W.differentiate [a
    a]
    insertUpZ a
    a (Just Stack a
    s) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { focus :: a
    W.focus = a
    a , down :: [a]
    W.down = Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s }

    -- | Insert an element after the focused one, and focus it
    insertDownZ :: a -> Zipper a -> Zipper a
    insertDownZ :: forall a. a -> Zipper a -> Zipper a
    insertDownZ a
    a Maybe (Stack a)
    Nothing = [a] -> Maybe (Stack a)
    forall a. [a] -> Maybe (Stack a)
    W.differentiate [a
    a]
    insertDownZ a
    a (Just Stack a
    s) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { focus :: a
    W.focus = a
    a, up :: [a]
    W.up = Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s }

    -- | Swap the focused element with the previous one
    swapUpZ :: Zipper a -> Zipper a
    swapUpZ :: forall a. Zipper a -> Zipper a
    swapUpZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    swapUpZ (Just Stack a
    s) | a
    u:[a]
    up <- Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { up :: [a]
    W.up = [a]
    up, down :: [a]
    W.down = a
    ua -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s}
    swapUpZ (Just Stack a
    s) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { up :: [a]
    W.up = [a] -> [a]
    forall a. [a] -> [a]
    reverse (Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s), down :: [a]
    W.down = [] }

    -- | Swap the focused element with the next one
    swapDownZ :: Zipper a -> Zipper a
    swapDownZ :: forall a. Zipper a -> Zipper a
    swapDownZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    swapDownZ (Just Stack a
    s) | a
    d:[a]
    down <- Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { down :: [a]
    W.down = [a]
    down, up :: [a]
    W.up = a
    da -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s }
    swapDownZ (Just Stack a
    s) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { up :: [a]
    W.up = [], down :: [a]
    W.down = [a] -> [a]
    forall a. [a] -> [a]
    reverse (Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s) }

    -- | Swap the focused element with the first one
    swapMasterZ :: Zipper a -> Zipper a
    swapMasterZ :: forall a. Zipper a -> Zipper a
    swapMasterZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    swapMasterZ (Just (W.Stack a
    f [a]
    up [a]
    down)) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    f [] ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    up [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a]
    down)

    -- ** Focus movement

    -- | Move the focus to the previous element
    focusUpZ :: Zipper a -> Zipper a
    focusUpZ :: forall a. Zipper a -> Zipper a
    focusUpZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    focusUpZ (Just Stack a
    s) | a
    u:[a]
    up <- Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    u [a]
    up (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    sa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s)
    focusUpZ (Just Stack a
    s) | [a] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([a] -> Bool) -> [a] -> Bool
    forall a b. (a -> b) -> a -> b
    $ Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s
    focusUpZ (Just (W.Stack a
    f [a]
    _ [a]
    down)) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack ([a] -> a
    forall a. HasCallStack => [a] -> a
    last [a]
    down) ([a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    tail ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    down) [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a
    f]) []

    -- | Move the focus to the next element
    focusDownZ :: Zipper a -> Zipper a
    focusDownZ :: forall a. Zipper a -> Zipper a
    focusDownZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    focusDownZ (Just Stack a
    s) | a
    d:[a]
    down <- Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    d (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    sa -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s) [a]
    down
    focusDownZ (Just Stack a
    s) | [a] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([a] -> Bool) -> [a] -> Bool
    forall a b. (a -> b) -> a -> b
    $ Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s
    focusDownZ (Just (W.Stack a
    f [a]
    up [a]
    _)) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack ([a] -> a
    forall a. HasCallStack => [a] -> a
    last [a]
    up) [] ([a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    tail ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    up) [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a
    f])

    -- | Move the focus to the first element
    focusMasterZ :: Zipper a -> Zipper a
    focusMasterZ :: forall a. Zipper a -> Zipper a
    focusMasterZ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    focusMasterZ (Just (W.Stack a
    f [a]
    up [a]
    down)) | Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ [a] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [a]
    up
        = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack ([a] -> a
    forall a. HasCallStack => [a] -> a
    last [a]
    up) [] ([a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    tail ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    up) [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a
    f] [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ [a]
    down)
    focusMasterZ (Just Stack a
    s) = Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s

    -- | Refocus a @Stack a@ on an element satisfying the predicate, or fail to
    --   @Nothing@.
    findS :: (a -> Bool) -> W.Stack a -> Maybe (W.Stack a)
    findS :: forall a. (a -> Bool) -> Stack a -> Maybe (Stack a)
    findS a -> Bool
    p Stack a
    st = Stack a
    st Stack a -> Maybe () -> Maybe (Stack a)
    forall a b. a -> Maybe b -> Maybe a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ (Bool -> Maybe ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> Maybe ()) -> (Stack a -> Bool) -> Stack a -> Maybe ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Bool
    p (a -> Bool) -> (Stack a -> a) -> Stack a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack a -> a
    forall a. Stack a -> a
    W.focus) Stack a
    st Maybe (Stack a) -> Maybe (Stack a) -> Maybe (Stack a)
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Stack a -> Maybe (Stack a)
    findUp Stack a
    st Maybe (Stack a) -> Maybe (Stack a) -> Maybe (Stack a)
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Stack a -> Maybe (Stack a)
    findDown Stack a
    st
      where findDown :: Stack a -> Maybe (Stack a)
    findDown = Maybe (Stack a) -> Maybe (Stack a)
    forall a. Zipper a -> Zipper a
    reverseZ (Maybe (Stack a) -> Maybe (Stack a))
    -> (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack a -> Maybe (Stack a)
    findUp (Stack a -> Maybe (Stack a))
    -> (Stack a -> Stack a) -> Stack a -> Maybe (Stack a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack a -> Stack a
    forall a. Stack a -> Stack a
    reverseS
            findUp :: Stack a -> Maybe (Stack a)
    findUp Stack a
    s | a
    u:[a]
    ups <- Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s = (if a -> Bool
    p a
    u then Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just else Stack a -> Maybe (Stack a)
    findUp)
                                       (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    u [a]
    ups (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s)
                     | Bool
    otherwise       = Maybe (Stack a)
    forall a. Maybe a
    Nothing

    -- | Refocus a @Zipper a@ on an element satisfying the predicate, or fail to
    --   @Nothing@.
    findZ :: (a -> Bool) -> Zipper a -> Zipper a
    findZ :: forall a. (a -> Bool) -> Zipper a -> Zipper a
    findZ a -> Bool
    _ Maybe (Stack a)
    Nothing   = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    findZ a -> Bool
    p (Just Stack a
    st) = (a -> Bool) -> Stack a -> Maybe (Stack a)
    forall a. (a -> Bool) -> Stack a -> Maybe (Stack a)
    findS a -> Bool
    p Stack a
    st

    -- ** Extraction

    -- | Get the focused element
    getFocusZ :: Zipper a -> Maybe a
    getFocusZ :: forall a. Zipper a -> Maybe a
    getFocusZ = (Stack a -> a) -> Maybe (Stack a) -> Maybe a
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Stack a -> a
    forall a. Stack a -> a
    W.focus

    -- | Get the element at a given index
    getIZ :: Int -> Zipper a -> Maybe a
    getIZ :: forall a. Int -> Zipper a -> Maybe a
    getIZ Int
    i = Int -> [a] -> Maybe a
    forall a. Int -> [a] -> Maybe a
    getI Int
    i ([a] -> Maybe a) -> (Zipper a -> [a]) -> Zipper a -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Zipper a -> [a]
    forall a. Maybe (Stack a) -> [a]
    W.integrate'

    -- ** Sorting

    -- | Sort a stack of elements supporting 'Ord'
    sortZ :: Ord a => Zipper a -> Zipper a
    sortZ :: forall a. Ord a => Zipper a -> Zipper a
    sortZ = (a -> a -> Ordering) -> Zipper a -> Zipper a
    forall a. (a -> a -> Ordering) -> Zipper a -> Zipper a
    sortByZ a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare

    -- | Sort a stack with an arbitrary sorting function
    sortByZ :: (a -> a -> Ordering) -> Zipper a -> Zipper a
    sortByZ :: forall a. (a -> a -> Ordering) -> Zipper a -> Zipper a
    sortByZ a -> a -> Ordering
    f = [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags ([Either a a] -> Zipper a)
    -> (Zipper a -> [Either a a]) -> Zipper a -> Zipper a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Either a a -> Either a a -> Ordering)
    -> [Either a a] -> [Either a a]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy ((a -> a -> Ordering) -> Either a a -> Either a a -> Ordering
    forall {t} {t} {t}. (t -> t -> t) -> Either t t -> Either t t -> t
    adapt a -> a -> Ordering
    f) ([Either a a] -> [Either a a])
    -> (Zipper a -> [Either a a]) -> Zipper a -> [Either a a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags
        where adapt :: (t -> t -> t) -> Either t t -> Either t t -> t
    adapt t -> t -> t
    g Either t t
    e1 Either t t
    e2 = t -> t -> t
    g (Either t t -> t
    forall a. Either a a -> a
    fromE Either t t
    e1) (Either t t -> t
    forall a. Either a a -> a
    fromE Either t t
    e2)

    -- ** Maps

    -- | Map a function over a stack. The boolean argument indcates whether
    -- the current element is the focused one
    mapZ :: (Bool -> a -> b) -> Zipper a -> Zipper b
    mapZ :: forall a b. (Bool -> a -> b) -> Zipper a -> Zipper b
    mapZ Bool -> a -> b
    f = [Either b b] -> Zipper b
    forall a. [Either a a] -> Zipper a
    fromTags ([Either b b] -> Zipper b)
    -> (Zipper a -> [Either b b]) -> Zipper a -> Zipper b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Either a a -> Either b b) -> [Either a a] -> [Either b b]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Bool -> a -> b) -> Either a a -> Either b b
    forall a b. (Bool -> a -> b) -> Either a a -> Either b b
    mapE Bool -> a -> b
    f) ([Either a a] -> [Either b b])
    -> (Zipper a -> [Either a a]) -> Zipper a -> [Either b b]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags

    -- | 'mapZ' without the 'Bool' argument
    mapZ_ :: (a -> b) -> Zipper a -> Zipper b
    mapZ_ :: forall a b. (a -> b) -> Zipper a -> Zipper b
    mapZ_ = (Bool -> a -> b) -> Zipper a -> Zipper b
    forall a b. (Bool -> a -> b) -> Zipper a -> Zipper b
    mapZ ((Bool -> a -> b) -> Zipper a -> Zipper b)
    -> ((a -> b) -> Bool -> a -> b) -> (a -> b) -> Zipper a -> Zipper b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b) -> Bool -> a -> b
    forall a b. a -> b -> a
    const

    -- | Monadic version of 'mapZ'
    mapZM :: Monad m => (Bool -> a -> m b) -> Zipper a -> m (Zipper b)
    mapZM :: forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Zipper a -> m (Zipper b)
    mapZM Bool -> a -> m b
    f Zipper a
    as = [Either b b] -> Zipper b
    forall a. [Either a a] -> Zipper a
    fromTags ([Either b b] -> Zipper b) -> m [Either b b] -> m (Zipper b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ((Either a a -> m (Either b b)) -> [Either a a] -> m [Either b b]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM ((Bool -> a -> m b) -> Either a a -> m (Either b b)
    forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Either a a -> m (Either b b)
    mapEM Bool -> a -> m b
    f) ([Either a a] -> m [Either b b])
    -> (Zipper a -> [Either a a]) -> Zipper a -> m [Either b b]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags) Zipper a
    as

    -- | Monadic version of 'mapZ_'
    mapZM_ :: Monad m => (a -> m b) -> Zipper a -> m (Zipper b)
    mapZM_ :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Zipper a -> m (Zipper b)
    mapZM_ = (Bool -> a -> m b) -> Zipper a -> m (Zipper b)
    forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Zipper a -> m (Zipper b)
    mapZM ((Bool -> a -> m b) -> Zipper a -> m (Zipper b))
    -> ((a -> m b) -> Bool -> a -> m b)
    -> (a -> m b)
    -> Zipper a
    -> m (Zipper b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> m b) -> Bool -> a -> m b
    forall a b. a -> b -> a
    const

    -- | Apply a function to the focused element
    onFocusedZ :: (a -> a) -> Zipper a -> Zipper a
    onFocusedZ :: forall a. (a -> a) -> Zipper a -> Zipper a
    onFocusedZ a -> a
    f = (Bool -> a -> a) -> Zipper a -> Zipper a
    forall a b. (Bool -> a -> b) -> Zipper a -> Zipper b
    mapZ ((Bool -> a -> a) -> Zipper a -> Zipper a)
    -> (Bool -> a -> a) -> Zipper a -> Zipper a
    forall a b. (a -> b) -> a -> b
    $ \Bool
    b a
    a -> if Bool
    b then a -> a
    f a
    a else a
    a

    -- | Monadic version of 'onFocusedZ'
    onFocusedZM :: Monad m => (a -> m a) -> Zipper a -> m (Zipper a)
    onFocusedZM :: forall (m :: * -> *) a.
    Monad m =>
    (a -> m a) -> Zipper a -> m (Zipper a)
    onFocusedZM a -> m a
    f = (Bool -> a -> m a) -> Zipper a -> m (Zipper a)
    forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Zipper a -> m (Zipper b)
    mapZM ((Bool -> a -> m a) -> Zipper a -> m (Zipper a))
    -> (Bool -> a -> m a) -> Zipper a -> m (Zipper a)
    forall a b. (a -> b) -> a -> b
    $ \Bool
    b a
    a -> if Bool
    b then a -> m a
    f a
    a else a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a

    -- | Apply a function to the element at the given index
    onIndexZ :: Int -> (a -> a) -> Zipper a -> Zipper a
    onIndexZ :: forall a. Int -> (a -> a) -> Zipper a -> Zipper a
    onIndexZ Int
    i a -> a
    _ Zipper a
    as | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 = Zipper a
    as
    onIndexZ Int
    i a -> a
    f Zipper a
    as = case Int -> [Either a a] -> ([Either a a], [Either a a])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    i ([Either a a] -> ([Either a a], [Either a a]))
    -> [Either a a] -> ([Either a a], [Either a a])
    forall a b. (a -> b) -> a -> b
    $ Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags Zipper a
    as of
                        ([Either a a]
    before, []) -> [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags [Either a a]
    before
                        ([Either a a]
    before, Either a a
    a:[Either a a]
    after) -> [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags ([Either a a] -> Zipper a) -> [Either a a] -> Zipper a
    forall a b. (a -> b) -> a -> b
    $ [Either a a]
    before [Either a a] -> [Either a a] -> [Either a a]
    forall a. [a] -> [a] -> [a]
    ++ (Bool -> a -> a) -> Either a a -> Either a a
    forall a b. (Bool -> a -> b) -> Either a a -> Either b b
    mapE ((a -> a) -> Bool -> a -> a
    forall a b. a -> b -> a
    const a -> a
    f) Either a a
    a Either a a -> [Either a a] -> [Either a a]
    forall a. a -> [a] -> [a]
    : [Either a a]
    after

    -- | Monadic version of 'onIndexZ'
    onIndexZM :: Monad m => Int -> (a -> m a) -> Zipper a -> m (Zipper a)
    onIndexZM :: forall (m :: * -> *) a.
    Monad m =>
    Int -> (a -> m a) -> Zipper a -> m (Zipper a)
    onIndexZM Int
    i a -> m a
    f Zipper a
    as = case Int -> [Either a a] -> ([Either a a], [Either a a])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    i ([Either a a] -> ([Either a a], [Either a a]))
    -> [Either a a] -> ([Either a a], [Either a a])
    forall a b. (a -> b) -> a -> b
    $ Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags Zipper a
    as of
                         ([Either a a]
    before, []) -> Zipper a -> m (Zipper a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
    forall a b. (a -> b) -> a -> b
    $ [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags [Either a a]
    before
                         ([Either a a]
    before, Either a a
    a:[Either a a]
    after) -> do Either a a
    a' <- (Bool -> a -> m a) -> Either a a -> m (Either a a)
    forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Either a a -> m (Either b b)
    mapEM ((a -> m a) -> Bool -> a -> m a
    forall a b. a -> b -> a
    const a -> m a
    f) Either a a
    a
                                                 Zipper a -> m (Zipper a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a)
    forall a b. (a -> b) -> a -> b
    $ [Either a a] -> Zipper a
    forall a. [Either a a] -> Zipper a
    fromTags ([Either a a] -> Zipper a) -> [Either a a] -> Zipper a
    forall a b. (a -> b) -> a -> b
    $ [Either a a]
    before [Either a a] -> [Either a a] -> [Either a a]
    forall a. [a] -> [a] -> [a]
    ++ Either a a
    a' Either a a -> [Either a a] -> [Either a a]
    forall a. a -> [a] -> [a]
    : [Either a a]
    after

    -- ** Filters

    -- | Fiter a stack according to a predicate. The refocusing behavior
    -- mimics XMonad's usual one. The boolean argument indicates whether the current
    -- element is the focused one.
    filterZ :: (Bool -> a -> Bool) -> Zipper a -> Zipper a
    filterZ :: forall a. (Bool -> a -> Bool) -> Zipper a -> Zipper a
    filterZ Bool -> a -> Bool
    _ Maybe (Stack a)
    Nothing = Maybe (Stack a)
    forall a. Maybe a
    Nothing
    filterZ Bool -> a -> Bool
    p (Just Stack a
    s) = case ( Bool -> a -> Bool
    p Bool
    True (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s)
                              , (a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> a -> Bool
    p Bool
    False) (Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s)
                              , (a -> Bool) -> [a] -> [a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> a -> Bool
    p Bool
    False) (Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s) ) of
                           (Bool
    True, [a]
    up', [a]
    down') -> Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { up :: [a]
    W.up = [a]
    up', down :: [a]
    W.down = [a]
    down' }
                           (Bool
    False, [], []) -> Maybe (Stack a)
    forall a. Maybe a
    Nothing
                           (Bool
    False, a
    f:[a]
    up', []) -> Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { focus :: a
    W.focus = a
    f, up :: [a]
    W.up = [a]
    up', down :: [a]
    W.down = [] }
                           (Bool
    False, [a]
    up', a
    f:[a]
    down') ->  Stack a -> Maybe (Stack a)
    forall a. a -> Maybe a
    Just Stack a
    s { focus :: a
    W.focus = a
    f
                                                            , up :: [a]
    W.up = [a]
    up'
                                                            , down :: [a]
    W.down = [a]
    down' }

    -- | 'filterZ' without the 'Bool' argument
    filterZ_ :: (a -> Bool) -> Zipper a -> Zipper a
    filterZ_ :: forall a. (a -> Bool) -> Zipper a -> Zipper a
    filterZ_ = (Bool -> a -> Bool) -> Zipper a -> Zipper a
    forall a. (Bool -> a -> Bool) -> Zipper a -> Zipper a
    filterZ ((Bool -> a -> Bool) -> Zipper a -> Zipper a)
    -> ((a -> Bool) -> Bool -> a -> Bool)
    -> (a -> Bool)
    -> Zipper a
    -> Zipper a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Bool) -> Bool -> a -> Bool
    forall a b. a -> b -> a
    const

    -- | Delete the focused element
    deleteFocusedZ :: Zipper a -> Zipper a
    deleteFocusedZ :: forall a. Zipper a -> Zipper a
    deleteFocusedZ = (Bool -> a -> Bool) -> Zipper a -> Zipper a
    forall a. (Bool -> a -> Bool) -> Zipper a -> Zipper a
    filterZ (\Bool
    b a
    _ -> Bool -> Bool
    not Bool
    b)

    -- | Delete the ith element
    deleteIndexZ :: Int -> Zipper a -> Zipper a
    deleteIndexZ :: forall a. Int -> Zipper a -> Zipper a
    deleteIndexZ Int
    i Zipper a
    z = let numbered :: Zipper (Int, a)
    numbered = ([Either (Int, a) (Int, a)] -> Zipper (Int, a)
    forall a. [Either a a] -> Zipper a
    fromTags ([Either (Int, a) (Int, a)] -> Zipper (Int, a))
    -> (Zipper a -> [Either (Int, a) (Int, a)])
    -> Zipper a
    -> Zipper (Int, a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int -> Either a a -> Either (Int, a) (Int, a))
    -> [Int] -> [Either a a] -> [Either (Int, a) (Int, a)]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Int -> Either a a -> Either (Int, a) (Int, a)
    forall {a} {b}. a -> Either b b -> Either (a, b) (a, b)
    number [Int
    0..] ([Either a a] -> [Either (Int, a) (Int, a)])
    -> (Zipper a -> [Either a a])
    -> Zipper a
    -> [Either (Int, a) (Int, a)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Zipper a -> [Either a a]
    forall a. Zipper a -> [Either a a]
    toTags) Zipper a
    z
                           number :: a -> Either b b -> Either (a, b) (a, b)
    number a
    j = (Bool -> b -> (a, b)) -> Either b b -> Either (a, b) (a, b)
    forall a b. (Bool -> a -> b) -> Either a a -> Either b b
    mapE (\Bool
    _ b
    a -> (a
    j,b
    a))
                       in ((Int, a) -> a) -> Zipper (Int, a) -> Zipper a
    forall a b. (a -> b) -> Zipper a -> Zipper b
    mapZ_ (Int, a) -> a
    forall a b. (a, b) -> b
    snd (Zipper (Int, a) -> Zipper a) -> Zipper (Int, a) -> Zipper a
    forall a b. (a -> b) -> a -> b
    $ ((Int, a) -> Bool) -> Zipper (Int, a) -> Zipper (Int, a)
    forall a. (a -> Bool) -> Zipper a -> Zipper a
    filterZ_ ((Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Int
    i) (Int -> Bool) -> ((Int, a) -> Int) -> (Int, a) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int, a) -> Int
    forall a b. (a, b) -> a
    fst) Zipper (Int, a)
    numbered

    -- ** Folds

    -- | Analogous to 'foldr'. The 'Bool' argument to the step functions indicates
    -- whether the current element is the focused one
    foldrZ :: (Bool -> a -> b -> b) -> b -> Zipper a -> b
    foldrZ :: forall a b. (Bool -> a -> b -> b) -> b -> Zipper a -> b
    foldrZ Bool -> a -> b -> b
    _ b
    b Maybe (Stack a)
    Nothing = b
    b
    foldrZ Bool -> a -> b -> b
    f b
    b (Just Stack a
    s) = let b1 :: b
    b1 = (a -> b -> b) -> b -> [a] -> b
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (Bool -> a -> b -> b
    f Bool
    False) b
    b (Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s)
                              b2 :: b
    b2 = Bool -> a -> b -> b
    f Bool
    True (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s) b
    b1
                              b3 :: b
    b3 = (b -> a -> b) -> b -> [a] -> b
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl ((a -> b -> b) -> b -> a -> b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ((a -> b -> b) -> b -> a -> b) -> (a -> b -> b) -> b -> a -> b
    forall a b. (a -> b) -> a -> b
    $ Bool -> a -> b -> b
    f Bool
    False) b
    b2 (Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s)
                          in b
    b3

    -- | Analogous to 'foldl'. The 'Bool' argument to the step functions indicates
    -- whether the current element is the focused one
    foldlZ :: (Bool -> b -> a -> b) -> b -> Zipper a -> b
    foldlZ :: forall b a. (Bool -> b -> a -> b) -> b -> Zipper a -> b
    foldlZ Bool -> b -> a -> b
    _ b
    b Maybe (Stack a)
    Nothing = b
    b
    foldlZ Bool -> b -> a -> b
    f b
    b (Just Stack a
    s) = let b1 :: b
    b1 = (a -> b -> b) -> b -> [a] -> b
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ((b -> a -> b) -> a -> b -> b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ((b -> a -> b) -> a -> b -> b) -> (b -> a -> b) -> a -> b -> b
    forall a b. (a -> b) -> a -> b
    $ Bool -> b -> a -> b
    f Bool
    False) b
    b (Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    s)
                              b2 :: b
    b2 = Bool -> b -> a -> b
    f Bool
    True b
    b1 (Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    s)
                              b3 :: b
    b3 = (b -> a -> b) -> b -> [a] -> b
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl (Bool -> b -> a -> b
    f Bool
    False) b
    b2 (Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    s)
                          in b
    b3

    -- | 'foldrZ' without the 'Bool' argument.
    foldrZ_ :: (a -> b -> b) -> b -> Zipper a -> b
    foldrZ_ :: forall a b. (a -> b -> b) -> b -> Zipper a -> b
    foldrZ_ = (Bool -> a -> b -> b) -> b -> Zipper a -> b
    forall a b. (Bool -> a -> b -> b) -> b -> Zipper a -> b
    foldrZ ((Bool -> a -> b -> b) -> b -> Zipper a -> b)
    -> ((a -> b -> b) -> Bool -> a -> b -> b)
    -> (a -> b -> b)
    -> b
    -> Zipper a
    -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b -> b) -> Bool -> a -> b -> b
    forall a b. a -> b -> a
    const

    -- | 'foldlZ' without the 'Bool' argument.
    foldlZ_ :: (b -> a -> b) -> b -> Zipper a -> b
    foldlZ_ :: forall b a. (b -> a -> b) -> b -> Zipper a -> b
    foldlZ_ = (Bool -> b -> a -> b) -> b -> Zipper a -> b
    forall b a. (Bool -> b -> a -> b) -> b -> Zipper a -> b
    foldlZ ((Bool -> b -> a -> b) -> b -> Zipper a -> b)
    -> ((b -> a -> b) -> Bool -> b -> a -> b)
    -> (b -> a -> b)
    -> b
    -> Zipper a
    -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (b -> a -> b) -> Bool -> b -> a -> b
    forall a b. a -> b -> a
    const

    -- | Find whether an element is present in a stack.
    elemZ :: Eq a => a -> Zipper a -> Bool
    elemZ :: forall a. Eq a => a -> Zipper a -> Bool
    elemZ a
    a = (Bool -> a -> Bool) -> Bool -> Zipper a -> Bool
    forall b a. (b -> a -> b) -> b -> Zipper a -> b
    foldlZ_ Bool -> a -> Bool
    step Bool
    False
        where step :: Bool -> a -> Bool
    step Bool
    True a
    _ = Bool
    True
              step Bool
    False a
    a' = a
    a' a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    a

    -- * Other utility functions

    -- | Safe version of '!!'
    getI :: Int -> [a] -> Maybe a
    getI :: forall a. Int -> [a] -> Maybe a
    getI Int
    i [a]
    xs = [a]
    xs [a] -> Int -> Maybe a
    forall a. [a] -> Int -> Maybe a
    !? Int
    i
    {-# DEPRECATED getI "Use XMonad.Prelude.(!?) instead." #-}

    -- | Map a function across both 'Left's and 'Right's.
    -- The 'Bool' argument is 'True' in a 'Right', 'False'
    -- in a 'Left'.
    mapE :: (Bool -> a -> b) -> Either a a -> Either b b
    mapE :: forall a b. (Bool -> a -> b) -> Either a a -> Either b b
    mapE Bool -> a -> b
    f (Left a
    a) = b -> Either b b
    forall a b. a -> Either a b
    Left (b -> Either b b) -> b -> Either b b
    forall a b. (a -> b) -> a -> b
    $ Bool -> a -> b
    f Bool
    False a
    a
    mapE Bool -> a -> b
    f (Right a
    a) = b -> Either b b
    forall a b. b -> Either a b
    Right (b -> Either b b) -> b -> Either b b
    forall a b. (a -> b) -> a -> b
    $ Bool -> a -> b
    f Bool
    True a
    a

    mapE_ :: (a -> b) -> Either a a -> Either b b
    mapE_ :: forall a b. (a -> b) -> Either a a -> Either b b
    mapE_ = (Bool -> a -> b) -> Either a a -> Either b b
    forall a b. (Bool -> a -> b) -> Either a a -> Either b b
    mapE ((Bool -> a -> b) -> Either a a -> Either b b)
    -> ((a -> b) -> Bool -> a -> b)
    -> (a -> b)
    -> Either a a
    -> Either b b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b) -> Bool -> a -> b
    forall a b. a -> b -> a
    const

    -- | Monadic version of 'mapE'
    mapEM :: Monad m => (Bool -> a -> m b) -> Either a a -> m (Either b b)
    mapEM :: forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Either a a -> m (Either b b)
    mapEM Bool -> a -> m b
    f (Left a
    a) = b -> Either b b
    forall a b. a -> Either a b
    Left (b -> Either b b) -> m b -> m (Either b b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Bool -> a -> m b
    f Bool
    False a
    a
    mapEM Bool -> a -> m b
    f (Right a
    a) = b -> Either b b
    forall a b. b -> Either a b
    Right (b -> Either b b) -> m b -> m (Either b b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Bool -> a -> m b
    f Bool
    True a
    a

    mapEM_ :: Monad m => (a -> m b) -> Either a a -> m (Either b b)
    mapEM_ :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Either a a -> m (Either b b)
    mapEM_ = (Bool -> a -> m b) -> Either a a -> m (Either b b)
    forall (m :: * -> *) a b.
    Monad m =>
    (Bool -> a -> m b) -> Either a a -> m (Either b b)
    mapEM ((Bool -> a -> m b) -> Either a a -> m (Either b b))
    -> ((a -> m b) -> Bool -> a -> m b)
    -> (a -> m b)
    -> Either a a
    -> m (Either b b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> m b) -> Bool -> a -> m b
    forall a b. a -> b -> a
    const

    -- | Get the @a@ from an @Either a a@
    fromE :: Either a a -> a
    fromE :: forall a. Either a a -> a
    fromE (Right a
    a) = a
    a
    fromE (Left a
    a) = a
    a

    -- | Tag the element with 'Right' if the property is true, 'Left' otherwise
    tagBy :: (a -> Bool) -> a -> Either a a
    tagBy :: forall a. (a -> Bool) -> a -> Either a a
    tagBy a -> Bool
    p a
    a = if a -> Bool
    p a
    a then a -> Either a a
    forall a b. b -> Either a b
    Right a
    a else a -> Either a a
    forall a b. a -> Either a b
    Left a
    a

    -- | Reverse a @Stack a@; O(1).
    reverseS :: W.Stack a -> W.Stack a
    reverseS :: forall a. Stack a -> Stack a
    reverseS (W.Stack a
    foc [a]
    ups [a]
    downs) = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    foc [a]
    downs [a]
    ups

    -- | Reverse a @Zipper a@; O(1).
    reverseZ :: Zipper a -> Zipper a
    reverseZ :: forall a. Zipper a -> Zipper a
    reverseZ = (Stack a -> Stack a
    forall a. Stack a -> Stack a
    reverseS (Stack a -> Stack a) -> Maybe (Stack a) -> Maybe (Stack a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>)