{-# LANGUAGE RecordWildCards #-}
module XMonad.Util.TreeZipper(
TreeZipper(..)
, cursor
, fromForest
, toForest
, getSubForest
, rootNode
, parent
, children
, nextChild
, previousChild
, nodeDepth
, nodeIndex
, followPath
, findChild
, isLeaf
, isRoot
, isLast
, isFirst
) where
import Data.Tree
data TreeZipper a = TreeZipper { TreeZipper a -> Tree a
tz_current :: Tree a
, TreeZipper a -> Forest a
tz_before :: Forest a
, TreeZipper a -> Forest a
tz_after :: Forest a
, TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents :: [(Forest a, a, Forest a)]
}
cursor :: TreeZipper a -> a
cursor :: TreeZipper a -> a
cursor = Tree a -> a
forall a. Tree a -> a
rootLabel (Tree a -> a) -> (TreeZipper a -> Tree a) -> TreeZipper a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current
fromForest :: Forest a -> TreeZipper a
fromForest :: Forest a -> TreeZipper a
fromForest [] = [Char] -> TreeZipper a
forall a. HasCallStack => [Char] -> a
error [Char]
"XMonad.Util.TreeZipper.fromForest: can't create a TreeZipper from an empty list!"
fromForest (Tree a
x:Forest a
xs) = TreeZipper :: forall a.
Tree a
-> Forest a
-> Forest a
-> [(Forest a, a, Forest a)]
-> TreeZipper a
TreeZipper { tz_current :: Tree a
tz_current = Tree a
x
, tz_before :: Forest a
tz_before = []
, tz_after :: Forest a
tz_after = Forest a
xs
, tz_parents :: [(Forest a, a, Forest a)]
tz_parents = []
}
toForest :: TreeZipper a -> Forest a
toForest :: TreeZipper a -> Forest a
toForest = TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
getSubForest (TreeZipper a -> Forest a)
-> (TreeZipper a -> TreeZipper a) -> TreeZipper a -> Forest a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> TreeZipper a
forall a. TreeZipper a -> TreeZipper a
rootNode
getSubForest :: TreeZipper a -> Forest a
getSubForest :: TreeZipper a -> Forest a
getSubForest TreeZipper{[(Forest a, a, Forest a)]
Forest a
Tree a
tz_parents :: [(Forest a, a, Forest a)]
tz_after :: Forest a
tz_before :: Forest a
tz_current :: Tree a
tz_parents :: forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_after :: forall a. TreeZipper a -> Forest a
tz_before :: forall a. TreeZipper a -> Forest a
tz_current :: forall a. TreeZipper a -> Tree a
..} = Forest a -> Forest a
forall a. [a] -> [a]
reverse Forest a
tz_before Forest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++ Tree a
tz_current Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
: Forest a
tz_after
rootNode :: TreeZipper a -> TreeZipper a
rootNode :: TreeZipper a -> TreeZipper a
rootNode = TreeZipper a -> TreeZipper a
forall a. TreeZipper a -> TreeZipper a
f
where
f :: TreeZipper a -> TreeZipper a
f TreeZipper a
z = TreeZipper a
-> (TreeZipper a -> TreeZipper a)
-> Maybe (TreeZipper a)
-> TreeZipper a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (TreeZipper a -> TreeZipper a
forall a. TreeZipper a -> TreeZipper a
g TreeZipper a
z) TreeZipper a -> TreeZipper a
f (Maybe (TreeZipper a) -> TreeZipper a)
-> Maybe (TreeZipper a) -> TreeZipper a
forall a b. (a -> b) -> a -> b
$ TreeZipper a -> Maybe (TreeZipper a)
forall a. TreeZipper a -> Maybe (TreeZipper a)
parent TreeZipper a
z
g :: TreeZipper a -> TreeZipper a
g TreeZipper a
z = TreeZipper a
-> (TreeZipper a -> TreeZipper a)
-> Maybe (TreeZipper a)
-> TreeZipper a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe TreeZipper a
z TreeZipper a -> TreeZipper a
g (Maybe (TreeZipper a) -> TreeZipper a)
-> Maybe (TreeZipper a) -> TreeZipper a
forall a b. (a -> b) -> a -> b
$ TreeZipper a -> Maybe (TreeZipper a)
forall a. TreeZipper a -> Maybe (TreeZipper a)
previousChild TreeZipper a
z
parent :: TreeZipper a -> Maybe (TreeZipper a)
parent :: TreeZipper a -> Maybe (TreeZipper a)
parent TreeZipper a
t = case TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents TreeZipper a
t of
(Forest a
xs,a
a,Forest a
ys) : [(Forest a, a, Forest a)]
ps -> TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just
TreeZipper :: forall a.
Tree a
-> Forest a
-> Forest a
-> [(Forest a, a, Forest a)]
-> TreeZipper a
TreeZipper { tz_current :: Tree a
tz_current = a -> Forest a -> Tree a
forall a. a -> Forest a -> Tree a
Node a
a (Forest a -> Forest a
forall a. [a] -> [a]
reverse (TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_before TreeZipper a
t) Forest a -> Forest a -> Forest a
forall a. [a] -> [a] -> [a]
++ TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current TreeZipper a
t Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
: TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_after TreeZipper a
t)
, tz_before :: Forest a
tz_before = Forest a
xs
, tz_after :: Forest a
tz_after = Forest a
ys
, tz_parents :: [(Forest a, a, Forest a)]
tz_parents = [(Forest a, a, Forest a)]
ps
}
[] -> Maybe (TreeZipper a)
forall a. Maybe a
Nothing
children :: TreeZipper a -> Maybe (TreeZipper a)
children :: TreeZipper a -> Maybe (TreeZipper a)
children TreeZipper a
z = case Tree a -> Forest a
forall a. Tree a -> Forest a
subForest (Tree a -> Forest a) -> Tree a -> Forest a
forall a b. (a -> b) -> a -> b
$ TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current TreeZipper a
z of
(Tree a
n:Forest a
xs) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just
TreeZipper :: forall a.
Tree a
-> Forest a
-> Forest a
-> [(Forest a, a, Forest a)]
-> TreeZipper a
TreeZipper { tz_current :: Tree a
tz_current = Tree a
n
, tz_before :: Forest a
tz_before = []
, tz_after :: Forest a
tz_after = Forest a
xs
, tz_parents :: [(Forest a, a, Forest a)]
tz_parents = (TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_before TreeZipper a
z, TreeZipper a -> a
forall a. TreeZipper a -> a
cursor TreeZipper a
z, TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_after TreeZipper a
z) (Forest a, a, Forest a)
-> [(Forest a, a, Forest a)] -> [(Forest a, a, Forest a)]
forall a. a -> [a] -> [a]
: TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents TreeZipper a
z
}
[] -> Maybe (TreeZipper a)
forall a. Maybe a
Nothing
nextChild :: TreeZipper a -> Maybe (TreeZipper a)
nextChild :: TreeZipper a -> Maybe (TreeZipper a)
nextChild TreeZipper a
z = case TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_after TreeZipper a
z of
(Tree a
n:Forest a
xs) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just
TreeZipper :: forall a.
Tree a
-> Forest a
-> Forest a
-> [(Forest a, a, Forest a)]
-> TreeZipper a
TreeZipper { tz_current :: Tree a
tz_current = Tree a
n
, tz_before :: Forest a
tz_before = TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current TreeZipper a
z Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
: TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_before TreeZipper a
z
, tz_after :: Forest a
tz_after = Forest a
xs
, tz_parents :: [(Forest a, a, Forest a)]
tz_parents = TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents TreeZipper a
z
}
[] -> Maybe (TreeZipper a)
forall a. Maybe a
Nothing
previousChild :: TreeZipper a -> Maybe (TreeZipper a)
previousChild :: TreeZipper a -> Maybe (TreeZipper a)
previousChild TreeZipper a
z = case TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_before TreeZipper a
z of
(Tree a
n:Forest a
xs) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just
TreeZipper :: forall a.
Tree a
-> Forest a
-> Forest a
-> [(Forest a, a, Forest a)]
-> TreeZipper a
TreeZipper { tz_current :: Tree a
tz_current = Tree a
n
, tz_before :: Forest a
tz_before = Forest a
xs
, tz_after :: Forest a
tz_after = TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current TreeZipper a
z Tree a -> Forest a -> Forest a
forall a. a -> [a] -> [a]
: TreeZipper a -> Forest a
forall a. TreeZipper a -> Forest a
tz_after TreeZipper a
z
, tz_parents :: [(Forest a, a, Forest a)]
tz_parents = TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents TreeZipper a
z
}
[] -> Maybe (TreeZipper a)
forall a. Maybe a
Nothing
nodeDepth :: TreeZipper a -> Int
nodeDepth :: TreeZipper a -> Int
nodeDepth = [(Forest a, a, Forest a)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([(Forest a, a, Forest a)] -> Int)
-> (TreeZipper a -> [(Forest a, a, Forest a)])
-> TreeZipper a
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents
nodeIndex :: TreeZipper a -> Int
nodeIndex :: TreeZipper a -> Int
nodeIndex = [Tree a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Tree a] -> Int)
-> (TreeZipper a -> [Tree a]) -> TreeZipper a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> [Tree a]
forall a. TreeZipper a -> Forest a
tz_before
followPath :: Eq b => (a -> b) -> [b] -> TreeZipper a -> Maybe (TreeZipper a)
followPath :: (a -> b) -> [b] -> TreeZipper a -> Maybe (TreeZipper a)
followPath a -> b
_ [] TreeZipper a
z = TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just TreeZipper a
z
followPath a -> b
f [b
x] TreeZipper a
z = (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
findChild (\a
y -> a -> b
f a
y b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
x) TreeZipper a
z
followPath a -> b
f (b
x:[b]
xs) TreeZipper a
z = (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
findChild (\a
y -> a -> b
f a
y b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
x) TreeZipper a
z Maybe (TreeZipper a)
-> (TreeZipper a -> Maybe (TreeZipper a)) -> Maybe (TreeZipper a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TreeZipper a -> Maybe (TreeZipper a)
forall a. TreeZipper a -> Maybe (TreeZipper a)
children Maybe (TreeZipper a)
-> (TreeZipper a -> Maybe (TreeZipper a)) -> Maybe (TreeZipper a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> b) -> [b] -> TreeZipper a -> Maybe (TreeZipper a)
forall b a.
Eq b =>
(a -> b) -> [b] -> TreeZipper a -> Maybe (TreeZipper a)
followPath a -> b
f [b]
xs
findChild :: (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
findChild :: (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
findChild a -> Bool
f TreeZipper a
z | a -> Bool
f (TreeZipper a -> a
forall a. TreeZipper a -> a
cursor TreeZipper a
z) = TreeZipper a -> Maybe (TreeZipper a)
forall a. a -> Maybe a
Just TreeZipper a
z
| Bool
otherwise = TreeZipper a -> Maybe (TreeZipper a)
forall a. TreeZipper a -> Maybe (TreeZipper a)
nextChild TreeZipper a
z Maybe (TreeZipper a)
-> (TreeZipper a -> Maybe (TreeZipper a)) -> Maybe (TreeZipper a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
forall a. (a -> Bool) -> TreeZipper a -> Maybe (TreeZipper a)
findChild a -> Bool
f
isLeaf :: TreeZipper a -> Bool
isLeaf :: TreeZipper a -> Bool
isLeaf = [Tree a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Tree a] -> Bool)
-> (TreeZipper a -> [Tree a]) -> TreeZipper a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree a -> [Tree a]
forall a. Tree a -> Forest a
subForest (Tree a -> [Tree a])
-> (TreeZipper a -> Tree a) -> TreeZipper a -> [Tree a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> Tree a
forall a. TreeZipper a -> Tree a
tz_current
isRoot :: TreeZipper a -> Bool
isRoot :: TreeZipper a -> Bool
isRoot = [(Forest a, a, Forest a)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([(Forest a, a, Forest a)] -> Bool)
-> (TreeZipper a -> [(Forest a, a, Forest a)])
-> TreeZipper a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> [(Forest a, a, Forest a)]
forall a. TreeZipper a -> [(Forest a, a, Forest a)]
tz_parents
isLast :: TreeZipper a -> Bool
isLast :: TreeZipper a -> Bool
isLast = [Tree a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Tree a] -> Bool)
-> (TreeZipper a -> [Tree a]) -> TreeZipper a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> [Tree a]
forall a. TreeZipper a -> Forest a
tz_after
isFirst :: TreeZipper a -> Bool
isFirst :: TreeZipper a -> Bool
isFirst = [Tree a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Tree a] -> Bool)
-> (TreeZipper a -> [Tree a]) -> TreeZipper a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeZipper a -> [Tree a]
forall a. TreeZipper a -> Forest a
tz_before