module Util.Trees (
edges
, paths, flatPaths
, find
, findAll
, findWithParents
, leaves
, filter
) where
import Prelude hiding (filter)
import qualified Data.Foldable as Foldable
import qualified Data.List as List
import Data.Maybe (mapMaybe)
import qualified Data.Tree as Tree
import Data.Tree (Tree(..))
import Control.Monad
edges :: [Tree a] -> [(a, a)]
edges :: forall a. [Tree a] -> [(a, a)]
edges = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a b. (a -> b) -> a -> b
$ \(Node a
val [Tree a]
subs) ->
[(a
val, a
sub_val) | Node a
sub_val [Tree a]
_ <- [Tree a]
subs] forall a. [a] -> [a] -> [a]
++ forall a. [Tree a] -> [(a, a)]
edges [Tree a]
subs
paths :: [Tree a] -> [(Tree a, [Tree a])]
paths :: forall a. [Tree a] -> [(Tree a, [Tree a])]
paths = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall {a}. [Tree a] -> Tree a -> [(Tree a, [Tree a])]
go [])
where
go :: [Tree a] -> Tree a -> [(Tree a, [Tree a])]
go [Tree a]
parents tree :: Tree a
tree@(Node a
_ [Tree a]
subs) =
(Tree a
tree, [Tree a]
parents) forall a. a -> [a] -> [a]
: forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Tree a] -> Tree a -> [(Tree a, [Tree a])]
go (Tree a
treeforall a. a -> [a] -> [a]
:[Tree a]
parents)) [Tree a]
subs
flatPaths :: [Tree a] -> [(a, [a], [a])]
flatPaths :: forall a. [Tree a] -> [(a, [a], [a])]
flatPaths = forall a b. (a -> b) -> [a] -> [b]
map forall {b} {b}. (Tree b, [Tree b]) -> (b, [b], [b])
flatten forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Tree a] -> [(Tree a, [Tree a])]
paths
where
flatten :: (Tree b, [Tree b]) -> (b, [b], [b])
flatten (Node b
val [Tree b]
subs, [Tree b]
parents) =
(b
val, forall a b. (a -> b) -> [a] -> [b]
map forall a. Tree a -> a
Tree.rootLabel [Tree b]
parents, forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Tree a -> [a]
Tree.flatten [Tree b]
subs)
find :: (a -> Bool) -> [Tree a] -> Maybe (Tree a)
find :: forall a. (a -> Bool) -> [Tree a] -> Maybe (Tree a)
find a -> Bool
p [Tree a]
trees = case forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (a -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Tree a -> a
rootLabel) [Tree a]
trees of
Maybe (Tree a)
Nothing -> forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a. (a -> Bool) -> [Tree a] -> Maybe (Tree a)
find a -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Tree a -> [Tree a]
subForest) [Tree a]
trees
Just Tree a
tree -> forall a. a -> Maybe a
Just Tree a
tree
findAll :: (a -> Bool) -> [Tree a] -> [Tree a]
findAll :: forall a. (a -> Bool) -> [Tree a] -> [Tree a]
findAll a -> Bool
f = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Tree a -> [Tree a]
node
where
node :: Tree a -> [Tree a]
node (Node a
a [Tree a]
trees)
| a -> Bool
f a
a = [forall a. a -> [Tree a] -> Tree a
Node a
a [Tree a]
trees]
| Bool
otherwise = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Tree a -> [Tree a]
node [Tree a]
trees
findWithParents :: (a -> Bool) -> [Tree a] -> Maybe (Tree a, [Tree a])
findWithParents :: forall a. (a -> Bool) -> [Tree a] -> Maybe (Tree a, [Tree a])
findWithParents a -> Bool
f = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (a -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Tree a -> a
Tree.rootLabel forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Tree a] -> [(Tree a, [Tree a])]
paths
leaves :: Tree a -> [a]
leaves :: forall a. Tree a -> [a]
leaves = forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList
filter :: (a -> Bool) -> Tree a -> Maybe (Tree a)
filter :: forall a. (a -> Bool) -> Tree a -> Maybe (Tree a)
filter a -> Bool
f = Tree a -> Maybe (Tree a)
node
where
node :: Tree a -> Maybe (Tree a)
node (Node a
a [Tree a]
trees)
| a -> Bool
f a
a = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> [Tree a] -> Tree a
Node a
a (forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Tree a -> Maybe (Tree a)
node [Tree a]
trees)
| Bool
otherwise = forall a. Maybe a
Nothing