Portability | portable |
---|---|

Stability | stable |

Maintainer | Uwe Schmidt (uwe\@fh-wedel.de) |

List arrows for tree processing.

Trees that implement the Data.Tree.Class interface, can be processed with these arrows.

- class (ArrowPlus a, ArrowIf a) => ArrowTree a where
- mkLeaf :: Tree t => b -> a c (t b)
- mkTree :: Tree t => b -> [t b] -> a c (t b)
- getChildren :: Tree t => a (t b) (t b)
- getNode :: Tree t => a (t b) b
- hasNode :: Tree t => (b -> Bool) -> a (t b) (t b)
- setChildren :: Tree t => [t b] -> a (t b) (t b)
- setNode :: Tree t => b -> a (t b) (t b)
- changeChildren :: Tree t => ([t b] -> [t b]) -> a (t b) (t b)
- changeNode :: Tree t => (b -> b) -> a (t b) (t b)
- processChildren :: Tree t => a (t b) (t b) -> a (t b) (t b)
- replaceChildren :: Tree t => a (t b) (t b) -> a (t b) (t b)
- (/>) :: Tree t => a b (t c) -> a (t c) d -> a b d
- (//>) :: Tree t => a b (t c) -> a (t c) d -> a b d
- (</) :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)
- deep :: Tree t => a (t b) c -> a (t b) c
- deepest :: Tree t => a (t b) c -> a (t b) c
- multi :: Tree t => a (t b) c -> a (t b) c
- processBottomUp :: Tree t => a (t b) (t b) -> a (t b) (t b)
- processTopDown :: Tree t => a (t b) (t b) -> a (t b) (t b)
- processBottomUpWhenNot :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)
- processTopDownUntil :: Tree t => a (t b) (t b) -> a (t b) (t b)
- insertChildrenAt :: Tree t => Int -> a (t b) (t b) -> a (t b) (t b)
- insertChildrenAfter :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)
- insertTreeTemplate :: Tree t => a (t b) (t b) -> [IfThen (a (t b) c) (a (t b) (t b))] -> a (t b) (t b)

- class Tree t

# Documentation

class (ArrowPlus a, ArrowIf a) => ArrowTree a whereSource

The interface for tree arrows

all functions have default implementations

mkLeaf :: Tree t => b -> a c (t b)Source

construct a leaf

mkTree :: Tree t => b -> [t b] -> a c (t b)Source

construct an inner node

getChildren :: Tree t => a (t b) (t b)Source

select the children of the root of a tree

getNode :: Tree t => a (t b) bSource

select the node info of the root of a tree

hasNode :: Tree t => (b -> Bool) -> a (t b) (t b)Source

select the attribute of the root of a tree

setChildren :: Tree t => [t b] -> a (t b) (t b)Source

substitute the children of the root of a tree

setNode :: Tree t => b -> a (t b) (t b)Source

substitute the attribute of the root of a tree

changeChildren :: Tree t => ([t b] -> [t b]) -> a (t b) (t b)Source

edit the children of the root of a tree

changeNode :: Tree t => (b -> b) -> a (t b) (t b)Source

edit the attribute of the root of a tree

processChildren :: Tree t => a (t b) (t b) -> a (t b) (t b)Source

apply an arrow element wise to all children of the root of a tree collect these results and substitute the children with this result

example: ` processChildren isText `

deletes all subtrees, for which isText does not hold

example: ` processChildren (none `when` isCmt) `

removes all children, for which isCmt holds

replaceChildren :: Tree t => a (t b) (t b) -> a (t b) (t b)Source

similar to processChildren, but the new children are computed by processing the whole input tree

example: ` replaceChildren (deep isText) `

selects all subtrees for which isText holds
and substitutes the children component of the root node with this list

(/>) :: Tree t => a b (t c) -> a (t c) d -> a b dSource

pronounced "slash", meaning g inside f

defined as ` f /> g = f >>> getChildren >>> g `

example: ` hasName "html" /> hasName "body" /> hasName "h1" `

This expression selects all "h1" elements in the "body" element of an "html" element, an expression, that corresponds 1-1 to the XPath selection path "html/body/h1"

(//>) :: Tree t => a b (t c) -> a (t c) d -> a b dSource

pronounced "double slash", meaning g arbitrarily deep inside f

defined as ` f //> g = f >>> getChildren >>> deep g `

example: ` hasName "html" //> hasName "table" `

This expression selects
all top level "table" elements within an "html" element, an expression.
Attantion: This does not correspond
to the XPath selection path "html//table". The latter on matches all table elements
even nested ones, but `//>`

gives in many cases the appropriate functionality.

(</) :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)Source

pronounced "outside" meaning f containing g

defined as ` f </ g = f `containing` (getChildren >>> g) `

deep :: Tree t => a (t b) c -> a (t b) cSource

recursively searches a whole tree for subtrees, for which a predicate holds.
The search is performed top down. When a tree is found, this becomes an element of the result
list. The tree found is not further examined for any subtress, for which the predicate also could hold.
See `multi`

for this kind of search.

example: ` deep isHtmlTable `

selects all top level table elements in a document
(with an appropriate definition for isHtmlTable) but no tables occuring within a table cell.

deepest :: Tree t => a (t b) c -> a (t b) cSource

recursively searches a whole tree for subrees, for which a predicate holds. The search is performed bottom up.

example: ` deepest isHtmlTable `

selects all innermost table elements in a document
but no table elements containing tables. See `deep`

and `multi`

for other search strategies.

multi :: Tree t => a (t b) c -> a (t b) cSource

recursively searches a whole tree for subtrees, for which a predicate holds. The search is performed top down. All nodes of the tree are searched, even within the subtrees of trees for which the predicate holds.

example: ` multi isHtmlTable `

selects all table elements, even nested ones.

processBottomUp :: Tree t => a (t b) (t b) -> a (t b) (t b)Source

recursively transforms a whole tree by applying an arrow to all subtrees, this is done bottom up depth first, leaves first, root as last tree

example: ` processBottomUp (getChildren `when` isHtmlFont) `

removes all font tags in a HTML document, even nested ones
(with an appropriate definition of isHtmlFont)

processTopDown :: Tree t => a (t b) (t b) -> a (t b) (t b)Source

similar to `processBottomUp`

, but recursively transforms a whole tree by applying an arrow to all subtrees
with a top down depth first traversal strategie. In many cases `processBottomUp`

and `processTopDown`

give same results.

processBottomUpWhenNot :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)Source

recursively transforms a whole tree by applying an arrow to all subtrees, but transformation stops when a predicte does not hold for a subtree, leaves are transformed first

processTopDownUntil :: Tree t => a (t b) (t b) -> a (t b) (t b)Source

recursively transforms a whole tree by applying an arrow to all subtrees, but transformation stops when a tree is successfully transformed. the transformation is done top down

example: ` processTopDownUntil (isHtmlTable `guards` tranformTable) `

transforms all top level table elements into something else, but inner tables remain unchanged

insertChildrenAt :: Tree t => Int -> a (t b) (t b) -> a (t b) (t b)Source

computes a list of trees by applying an arrow to the input and inserts this list in front of index i in the list of children

example: ` insertChildrenAt 0 (deep isCmt) `

selects all subtrees for which isCmt holds
and copies theses in front of the existing children

insertChildrenAfter :: Tree t => a (t b) (t b) -> a (t b) (t b) -> a (t b) (t b)Source

similar to `insertChildrenAt`

, but the insertion position is searched with a predicate

insertTreeTemplate :: Tree t => a (t b) (t b) -> [IfThen (a (t b) c) (a (t b) (t b))] -> a (t b) (t b)Source

an arrow for inserting a whole subtree with some holes in it (a template) into a document. The holes can be filled with contents from the input.

Example

insertTreeTemplateTest :: ArrowXml a => a b XmlTree insertTreeTemplateTest = doc >>> insertTreeTemplate template pattern where doc -- the input data = constA "<x><y>The Title</y><z>The content</z></x>" >>> xread template -- the output template with 2 holes: xxx and yyy = constA "<html><head><title>xxx</title></head><body><h1>yyy</h1></body></html>" >>> xread pattern = [ hasText (== "xxx") -- fill the xxx hole with the input contents from element "x/y" :-> ( getChildren >>> hasName "y" >>> deep isText ) , hasText (== "yyy") -- fill the yyy hole with the input contents from element "x/z" :-> ( getChildren >>> hasName "z" >>> getChildren ) ]

computes the XML tree for the following document

"<html><head><title>The Title</title></head><body><h1>The content</h1></body></html>"