{-# 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 :: Zipper a
emptyZ = Zipper a
forall a. Maybe a
Nothing

singletonZ :: a -> Zipper a
singletonZ :: a -> Zipper a
singletonZ a
a = Stack a -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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 :: [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 :: Zipper a -> ([a], Maybe Int)
toIndex Zipper 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 (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 :: [Either a a] -> Zipper a
fromTags = ([a], Maybe a, [a]) -> Zipper a
forall a. ([a], Maybe a, [a]) -> Maybe (Stack a)
finalize (([a], Maybe a, [a]) -> Zipper a)
-> ([Either a a] -> ([a], Maybe a, [a]))
-> [Either a a]
-> Zipper 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 (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 :: Zipper a -> [Either a a]
toTags Zipper 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 :: a -> Zipper a -> Zipper a
insertUpZ a
a Zipper a
Nothing = [a] -> Zipper a
forall a. [a] -> Maybe (Stack a)
W.differentiate [a
a]
insertUpZ a
a (Just Stack a
s) = Stack a -> Zipper 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 :: a -> Zipper a -> Zipper a
insertDownZ a
a Zipper a
Nothing = [a] -> Zipper a
forall a. [a] -> Maybe (Stack a)
W.differentiate [a
a]
insertDownZ a
a (Just Stack a
s) = Stack a -> Zipper 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 :: Zipper a -> Zipper a
swapUpZ Zipper a
Nothing = Zipper 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 -> Zipper 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 -> Zipper 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 :: Zipper a -> Zipper a
swapDownZ Zipper a
Nothing = Zipper 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 -> Zipper 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 -> Zipper 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 :: Zipper a -> Zipper a
swapMasterZ Zipper a
Nothing = Zipper a
forall a. Maybe a
Nothing
swapMasterZ (Just (W.Stack a
f [a]
up [a]
down)) = Stack a -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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 :: Zipper a -> Zipper a
focusUpZ Zipper a
Nothing = Zipper 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 -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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 (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 -> Zipper a
forall a. a -> Maybe a
Just Stack a
s
focusUpZ (Just (W.Stack a
f [a]
_ [a]
down)) = Stack a -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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. [a] -> a
last [a]
down) ([a] -> [a]
forall a. [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 :: Zipper a -> Zipper a
focusDownZ Zipper a
Nothing = Zipper 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 -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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 (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 -> Zipper a
forall a. a -> Maybe a
Just Stack a
s
focusDownZ (Just (W.Stack a
f [a]
up [a]
_)) = Stack a -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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. [a] -> a
last [a]
up) [] ([a] -> [a]
forall a. [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 :: Zipper a -> Zipper a
focusMasterZ Zipper a
Nothing = Zipper 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 (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
up
    = Stack a -> Zipper a
forall a. a -> Maybe a
Just (Stack a -> Zipper a) -> Stack a -> Zipper 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. [a] -> a
last [a]
up) [] ([a] -> [a]
forall a. [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 -> Zipper 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 :: (a -> Bool) -> Stack a -> Maybe (Stack a)
findS a -> Bool
p Stack a
st = Stack a
st Stack a -> Maybe () -> Maybe (Stack 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 (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 (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 :: (a -> Bool) -> Zipper a -> Zipper a
findZ a -> Bool
_ Zipper a
Nothing   = Zipper a
forall a. Maybe a
Nothing
findZ a -> Bool
p (Just Stack a
st) = (a -> Bool) -> Stack a -> Zipper 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 :: Zipper a -> Maybe a
getFocusZ = (Stack a -> a) -> Zipper a -> Maybe a
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 :: 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 :: 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 :: (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 :: (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_ :: (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 :: (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)
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_ :: (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 :: (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 :: (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 (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 :: 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 :: 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 (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 (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 :: (Bool -> a -> Bool) -> Zipper a -> Zipper a
filterZ Bool -> a -> Bool
_ Zipper a
Nothing = Zipper 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 -> Zipper a
forall a. a -> Maybe a
Just Stack a
s { up :: [a]
W.up = [a]
up', down :: [a]
W.down = [a]
down' }
                       (Bool
False, [], []) -> Zipper a
forall a. Maybe a
Nothing
                       (Bool
False, a
f:[a]
up', []) -> Stack a -> Zipper 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 -> Zipper 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_ :: (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 :: 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 :: 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 :: (Bool -> a -> b -> b) -> b -> Zipper a -> b
foldrZ Bool -> a -> b -> b
_ b
b Zipper 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 (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 (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 :: (Bool -> b -> a -> b) -> b -> Zipper a -> b
foldlZ Bool -> b -> a -> b
_ b
b Zipper 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 (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 (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_ :: (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_ :: (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 :: 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 :: 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 :: (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_ :: (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 :: (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_ :: (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 :: 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 :: (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 :: 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 :: Zipper a -> Zipper a
reverseZ = (Stack a -> Stack a
forall a. Stack a -> Stack a
reverseS (Stack a -> Stack a) -> Zipper a -> Zipper a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)