Documentation
¶
Index ¶
- func BottomUp[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, ERR]
- func BottomUpFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) ...
- func BottomUpFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func BreadthFirst[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadOnly, UniDir, ERR]
- func BreadthFirstFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) ...
- func BreadthFirstFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func DiffTree[I, J, A any, RET TReturnOne, RW any, DIR any, ERR any, DRET TReturnOne, ...](right mo.Option[A], ...) ...
- func DiffTreeI[I, J, A any, RET TReturnOne, RW, DIR, ERR any, DRET TReturnOne, ERRI TPure](right mo.Option[A], ...) ...
- func DiffTreeT2[I, J, A any, RET TReturnOne, RW any, DIR any, ERR any, DRET TReturnOne, ...](...) ...
- func DiffTreeT2I[I, J, A any, RET TReturnOne, RW, DIR, ERR any, DRET TReturnOne, ERRI TPure](...) ...
- func EqPath[I any, ERR TPure](right *PathNode[I], eq Predicate[lo.Tuple2[I, I], ERR]) ...
- func EqPathT2[I any, ERR TPure](eq Predicate[lo.Tuple2[I, I], ERR]) ...
- func EqTree[I comparable, A, ERR any, PERR TPure](right TreeNode[I, A, ERR], eq Predicate[lo.Tuple2[A, A], PERR]) ...
- func EqTreeI[I, A, ERR any, PERR, IERR TPure](right TreeNode[I, A, ERR], ixMatch Predicate[lo.Tuple2[I, I], PERR], ...) ...
- func EqTreeT2[I comparable, A, ERR any, PERR TPure](eq Predicate[lo.Tuple2[A, A], PERR]) ...
- func EqTreeT2I[I, A, ERR any, IERR, PERR TPure](ixMatch Predicate[lo.Tuple2[I, I], IERR], eq Predicate[lo.Tuple2[A, A], PERR]) ...
- func MergeTree[I, J, A, RET, SRET any, RW any, SRW ReadWrite, DIR, SDIR, ERR, SERR any](right A, children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func MergeTreeT2[I, J, A, RET, SRET any, RW any, SRW ReadWrite, DIR, SDIR, ERR, SERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func OTree[I comparable, X, ERR any]() ...
- func OTreeFrom[X any, I comparable, J any, S any, T any, RET any, RW any, DIR any, ERR any](...) *lTree[X, I, J, S, T, RET, RW, DIR, ERR]
- func OTreeFromI[X any, I any, J any, S any, T any, RET any, RW any, DIR any, ERR any](...) *lTree[X, I, J, S, T, RET, RW, DIR, ERR]
- func OTreeI[I any, X, ERR any](ixmatch func(a, b I) bool) ...
- func OTreeOpt[I comparable, X, ERR any]() ...
- func OTreeOptFrom[X any, I comparable, J any, S any, T any, RET any, RW any, DIR any, ERR any](...) *loTree[X, I, J, S, T, RET, RW, DIR, ERR]
- func OTreeOptFromI[X any, I any, J any, S any, T any, RET any, RW any, DIR any, ERR any](...) *loTree[X, I, J, S, T, RET, RW, DIR, ERR]
- func OTreeOptI[I any, X, ERR any](ixmatch func(a, b I) bool) ...
- func PathValue[I any]() ...
- func ReIndexedTree[A any, I comparable, J comparable, L any, IRET TReturnOne, IRW any, IDIR any, ...](ixmap Optic[L, I, I, J, J, IRET, IRW, IDIR, ERR]) ...
- func ReIndexedTreeP[A, B, I, J, L any, IRET TReturnOne, IRW any, IDIR any, ERR any](ixmap Optic[L, I, I, J, J, IRET, IRW, IDIR, ERR], ixmatch func(I, I) bool, ...) ...
- func ResolvePath[I, A, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], resolvePath *PathNode[I]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadWrite, UniDir, ERR]
- func Rewrite[I, A, RET any, RW TReadWrite, DIR, ERR any, ORET TReturnOne, OERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func RewriteI[I, A, RET any, RW TReadWrite, DIR, ERR any, ORET TReturnOne, OERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func RewriteOp[A any](rewriteHandler func(node A) (A, bool)) ...
- func RewriteOpE[A any](rewriteHandler func(ctx context.Context, node A) (A, bool, error)) ...
- func RewriteOpI[I, A any](rewriteHandler func(index *PathNode[I], node A) (A, bool)) ...
- func RewriteOpIE[I, A any](...) ...
- func TopDown[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, ERR]
- func TopDownFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) ...
- func TopDownFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], ...) ...
- func TopDownMatch[I, S, RET any, RW any, DIR any, ERR, MERR any](children Optic[I, S, S, S, S, RET, RW, DIR, ERR], matcher Predicate[S, MERR]) Optic[*PathNode[I], S, S, S, S, ReturnMany, RW, UniDir, ERR]
- func TopDownMatchI[I, S, RET any, RW any, DIR any, ERR, MERR any](children Optic[I, S, S, S, S, RET, RW, DIR, ERR], ...) Optic[*PathNode[I], S, S, S, S, ReturnMany, RW, UniDir, ERR]
- func TraversePath[I any]() ...
- func TraverseTreeChildren[I comparable, A, ERR any]() ...
- func TraverseTreeChildrenI[I, A, ERR any](ixmatch func(a, b I) bool) ...
- func TraverseTreeChildrenP[I, A, B any, ERR any, PERR TPure](ixMatch Predicate[lo.Tuple2[I, I], PERR]) ...
- func TreeChildren[I, A, ERR any]() ...
- func TreeValue[I, A, ERR any]() ...
- func WithChildPath[I comparable, S, A any, RET any, RW, DIR, ERR any](...) ...
- func WithChildPathI[I, S, A any, RET any, RW, DIR, ERR any](...) ...
- type PathNode
- type TreeNode
- func Tree[T any](value T, children ...Collection[int, TreeNode[int, T, Pure], Pure]) TreeNode[int, T, Pure]
- func TreeE[T any](value T, children ...Collection[int, TreeNode[int, T, Err], Err]) TreeNode[int, T, Err]
- func TreeI[I any, T any](value T, ixMatch func(a, b I) bool, ...) TreeNode[I, T, Pure]
- func TreeIE[I any, T any, ERR any](value T, ixMatch func(a, b I) bool, ...) TreeNode[I, T, ERR]
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BottomUp ¶
func BottomUp[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, ERR]
BottomUp is a [Traversal] that walks the tree in a bottom up order. During the traversal the child index is used to construct a path represented as a PathNode
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order C,B,D,A See: - BottomUpFiltered for a filtering version - TopDown for a top down version - BreadthFirst for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
optic := BottomUp(
children,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [C B D A]
func BottomUpFiltered ¶
func BottomUpFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, CompositionTree[ERR, ERRP]]
BottomUpFiltered is a [Traversal] that walks the tree in a bottom up order and filters out branches that don't match the predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is applied applied in top down order including the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order C,B,D,A See: - BottomUpFilteredI for an index aware predicate version. - BottomUp for a simpler non filtering version. - TopDownFiltered for a top down version - BreadthFirstFiltered for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose(
OTree[int, string, Pure]().Value(),
Ne("FilterMe"),
)
optic := BottomUpFiltered(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [C B D A]
func BottomUpFilteredI ¶
func BottomUpFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred PredicateI[*PathNode[I], A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, CompositionTree[ERR, ERRP]]
BottomUpFilteredI is a [Traversal] that walks the tree in a bottom up order and filters out branches that don't match the index aware predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is applied applied in top down order including the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order C,B,D,A See: - BottomUpFiltered for a simpler non index aware predicate version. - BottomUp for a simpler non filtering version. - TopDownFilteredI for a top down version - BreadthFirstFilteredI for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose3(
ValueIIndex[*PathNode[int], TreeNode[int, string, Pure]](),
EqPath(Path(0, 1), EqT2[int]()),
Not(),
)
optic := BottomUpFilteredI(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [C B D A]
func BreadthFirst ¶
func BreadthFirst[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadOnly, UniDir, ERR]
BreadthFirst is a [Traversal] that walks the tree in a breadth first order. During the traversal the child index is used to construct a path represented as a PathNode
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,D,C See: - BreadthFirstFiltered for a filtering version - TopDown for a top down version - BottomUp for a bottom up version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
optic := BreadthFirst(
children,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B D C]
func BreadthFirstFiltered ¶
func BreadthFirstFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadOnly, UniDir, CompositionTree[ERR, ERRP]]
BreadthFirstFiltered is a [Traversal] that walks the tree in a breadth first order and filters out branches that don't match the predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is applied applied in top down order including the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,D,C See: - BreadthFirstFiltered for a simpler non index aware predicate version. - BreadthFirst for a simpler non filtering version. - TopDownFiltered for a top down version - BottomUpFiltered for a bottom up version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose(
OTree[int, string, Pure]().Value(),
Ne("FilterMe"),
)
optic := BreadthFirstFiltered(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B D C]
func BreadthFirstFilteredI ¶
func BreadthFirstFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred PredicateI[*PathNode[I], A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadOnly, UniDir, CompositionTree[ERR, ERRP]]
BreadthFirstFilteredI is a [Traversal] that walks the tree in a breadth first order and filters out branches that don't match the index aware predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is applied applied in top down order including the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,D,C See: - BreadthFirstFiltered for a simpler non index aware predicate version. - BreadthFirst for a simpler non filtering version. - TopDownFilteredI for a top down version - BottomUpFilteredI for a bottom up version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose3(
ValueIIndex[*PathNode[int], TreeNode[int, string, Pure]](),
EqPath(Path(0, 1), EqT2[int]()),
Not(),
)
optic := BreadthFirstFilteredI(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B D C]
func DiffTree ¶
func DiffTree[I, J, A any, RET TReturnOne, RW any, DIR any, ERR any, DRET TReturnOne, ERRI TPure](right mo.Option[A], children Optic[J, A, A, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR], threshold float64, distance Operation[lo.Tuple2[A, A], float64, DRET, ERR], ixMatch Predicate[lo.Tuple2[I, I], ERRI], filterDiff DiffType, detectPosChange bool) Optic[Diff[*PathNode[I], A], mo.Option[A], mo.Option[A], mo.Option[A], mo.Option[A], ReturnMany, RW, UniDir, ERR]
func DiffTreeI ¶
func DiffTreeI[I, J, A any, RET TReturnOne, RW, DIR, ERR any, DRET TReturnOne, ERRI TPure](right mo.Option[A], children Optic[J, A, A, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR], threshold float64, distance Operation[lo.Tuple2[ValueI[*PathNode[I], A], ValueI[*PathNode[I], A]], float64, DRET, ERR], ixMatch Predicate[lo.Tuple2[I, I], ERRI], filterDiff DiffType, detectPosChange bool) Optic[Diff[*PathNode[I], A], mo.Option[A], mo.Option[A], mo.Option[A], mo.Option[A], ReturnMany, RW, UniDir, ERR]
func DiffTreeT2 ¶
func DiffTreeT2[I, J, A any, RET TReturnOne, RW any, DIR any, ERR any, DRET TReturnOne, ERRI TPure](children Optic[J, A, A, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR], threshold float64, distance Operation[lo.Tuple2[A, A], float64, DRET, ERR], ixMatch Predicate[lo.Tuple2[I, I], ERRI], filterDiff DiffType, detectPosChange bool) Optic[Diff[*PathNode[I], A], lo.Tuple2[mo.Option[A], mo.Option[A]], lo.Tuple2[mo.Option[A], mo.Option[A]], mo.Option[A], mo.Option[A], ReturnMany, RW, UniDir, ERR]
func DiffTreeT2I ¶
func DiffTreeT2I[I, J, A any, RET TReturnOne, RW, DIR, ERR any, DRET TReturnOne, ERRI TPure](children Optic[J, A, A, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR], threshold float64, distance Operation[lo.Tuple2[ValueI[*PathNode[I], A], ValueI[*PathNode[I], A]], float64, DRET, ERR], ixMatch Predicate[lo.Tuple2[I, I], ERRI], filterDiff DiffType, detectPosChange bool) Optic[Diff[*PathNode[I], A], lo.Tuple2[mo.Option[A], mo.Option[A]], lo.Tuple2[mo.Option[A], mo.Option[A]], mo.Option[A], mo.Option[A], ReturnMany, RW, UniDir, ERR]
When a node is added only the added node is reported in the diff not all of it's children recursively.
func MergeTree ¶
func MergeTree[I, J, A, RET, SRET any, RW any, SRW ReadWrite, DIR, SDIR, ERR, SERR any](right A, children Optic[I, A, A, A, A, RET, RW, DIR, ERR], childrenCol Optic[J, A, A, Collection[I, A, SERR], Collection[I, A, SERR], SRET, SRW, SDIR, SERR]) Optic[Void, mo.Option[A], mo.Option[A], mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, CompositionTree[ERR, SERR]]
func MergeTreeT2 ¶
func MergeTreeT2[I, J, A, RET, SRET any, RW any, SRW ReadWrite, DIR, SDIR, ERR, SERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], childrenCol Optic[J, A, A, Collection[I, A, SERR], Collection[I, A, SERR], SRET, SRW, SDIR, SERR]) Optic[Void, lo.Tuple2[mo.Option[A], mo.Option[A]], lo.Tuple2[mo.Option[A], mo.Option[A]], mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, CompositionTree[ERR, SERR]]
func OTreeFromI ¶
func OTreeOptFrom ¶
func OTreeOptFromI ¶
func ReIndexedTree ¶
func ReIndexedTree[A any, I comparable, J comparable, L any, IRET TReturnOne, IRW any, IDIR any, ERR any](ixmap Optic[L, I, I, J, J, IRET, IRW, IDIR, ERR]) Optic[Void, mo.Option[TreeNode[I, A, ERR]], mo.Option[TreeNode[I, A, ERR]], mo.Option[TreeNode[J, A, ERR]], mo.Option[TreeNode[J, A, ERR]], ReturnOne, IRW, IDIR, ERR]
func ReIndexedTreeP ¶
func ReIndexedTreeP[A, B, I, J, L any, IRET TReturnOne, IRW any, IDIR any, ERR any](ixmap Optic[L, I, I, J, J, IRET, IRW, IDIR, ERR], ixmatch func(I, I) bool, ixmatchj func(J, J) bool) Optic[Void, mo.Option[TreeNode[I, A, ERR]], mo.Option[TreeNode[I, B, ERR]], mo.Option[TreeNode[J, A, ERR]], mo.Option[TreeNode[J, B, ERR]], ReturnOne, IRW, IDIR, ERR]
func ResolvePath ¶
func ResolvePath[I, A, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], resolvePath *PathNode[I]) Optic[*PathNode[I], A, A, A, A, ReturnMany, ReadWrite, UniDir, ERR]
The ResolvePath combinator returns an optic that focuses the child element wth the given path.
Example ¶
data := Tree(
"alpha",
ValCol(
Tree("beta"),
Tree("gamma",
ValCol(Tree("delta")),
),
),
)
optic := ResolvePath(TraverseTreeChildren[int, string, Pure](), Path(1, 0))
var result TreeNode[int, string, Pure]
var ok bool
result, ok = MustGetFirst(optic, data)
fmt.Println(result, ok)
modifyResult := MustSet(optic, Tree("omega"), data)
fmt.Println(modifyResult)
Output: {delta : Col[]} true {alpha : Col[0:{beta : Col[]} 1:{gamma : Col[0:{omega : Col[]}]}]}
func Rewrite ¶
func Rewrite[I, A, RET any, RW TReadWrite, DIR, ERR any, ORET TReturnOne, OERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], op Operation[A, mo.Option[A], ORET, OERR]) Optic[Void, A, A, A, A, ReturnOne, ReadOnly, UniDir, CompositionTree[ERR, OERR]]
The Rewrite combinator focuses a rewritten version of the source tree.
The op parameter can be constructed using the RewriteOp family of constructors.
The tree is rewritten by applying the op to very node in the tree. If the op returns a some option then the value replaces the node in the tree. If the op returns none then the node remains unaltered. If any node was replaced then the whole process is run again until the op returns none for all nodes in the tree.
See:
Example ¶
tree := Tree[any](
"+",
ValCol(
Tree[any](
"+",
ValCol(
Tree[any](1),
Tree[any](2),
),
),
Tree[any](3),
),
)
opName := Compose(
TreeValue[int, any, Pure](),
DownCast[any, string](),
)
value := Compose(
TreeValue[int, any, Pure](),
DownCast[any, int](),
)
//Rewrite handler that evaluates the "+" function
rewriteHandler := RewriteOp(func(tree TreeNode[int, any, Pure]) (TreeNode[int, any, Pure], bool) {
//If all the children are literal values we may be able to evaluate the expression
childrenAllValues, _ := MustGetFirst(
All(
OTree[int, any, Pure]().Children().Traverse(),
NotEmpty(value),
),
tree,
)
if childrenAllValues {
funcName, _ := MustGetFirst(opName, tree)
switch funcName {
case "+":
sumParams, _ := MustGetFirst(Reduce(Compose(OTree[int, any, Pure]().Children().Traverse(), value), Sum[int]()), tree)
return Tree[any](sumParams), true
}
}
return tree, false
})
newTree := MustGet(Rewrite(TraverseTreeChildren[int, any, Pure](), rewriteHandler), tree)
fmt.Println(newTree)
data := lo.T2("alpha", tree)
newTuple := MustModify(T2B[string, TreeNode[int, any, Pure]](), Rewrite(TraverseTreeChildren[int, any, Pure](), rewriteHandler), data)
fmt.Println(newTuple.A, newTuple.B)
Output: {6 : Col[]} alpha {6 : Col[]}
func RewriteI ¶
func RewriteI[I, A, RET any, RW TReadWrite, DIR, ERR any, ORET TReturnOne, OERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], op OperationI[*PathNode[I], A, mo.Option[A], ORET, OERR]) Optic[Void, A, A, A, A, ReturnOne, ReadOnly, UniDir, CompositionTree[ERR, OERR]]
The RewriteI combinator focuses a rewritten version of the source tree.
The op parameter can be constructed using the RewriteOp family of constructors.
The tree is rewritten by applying the op to very node in the tree. If the op returns a some option then the value replaces the node in the tree. If the op returns none then the node remains unaltered. If any node was replaced then the whole process is run again until the op returns none for all nodes in the tree.
See:
Example ¶
tree := Tree[any](
"+",
ValCol(
Tree[any](
"+",
ValCol(
Tree[any](1),
Tree[any](2),
),
),
Tree[any](3),
),
)
opName := Compose(
TreeValue[int, any, Pure](),
DownCast[any, string](),
)
value := Compose(
TreeValue[int, any, Pure](),
DownCast[any, int](),
)
//Rewrite handler that evaluates the "+" function
rewriteHandler := RewriteOpI(func(path *PathNode[int], tree TreeNode[int, any, Pure]) (TreeNode[int, any, Pure], bool) {
//Use index to prevent evaluation at the root of the tree
if path == nil {
return tree, false
}
//If all the children are literal values we may be able to evaluate the expression
childrenAllValues, _ := MustGetFirst(All(OTree[int, any, Pure]().Children().Traverse(), NotEmpty(value)), tree)
if childrenAllValues {
funcName, _ := MustGetFirst(opName, tree)
switch funcName {
case "+":
sumParams, _ := MustGetFirst(Reduce(Compose(OTree[int, any, Pure]().Children().Traverse(), value), Sum[int]()), tree)
return Tree[any](sumParams), true
}
}
return tree, false
})
newTree := MustGet(RewriteI(TraverseTreeChildren[int, any, Pure](), rewriteHandler), tree)
fmt.Println(newTree)
data := lo.T2("alpha", tree)
newTuple := MustModify(T2B[string, TreeNode[int, any, Pure]](), RewriteI(TraverseTreeChildren[int, any, Pure](), rewriteHandler), data)
fmt.Println(newTuple.A, newTuple.B)
Output: {+ : Col[0:{3 : Col[]} 1:{3 : Col[]}]} alpha {+ : Col[0:{3 : Col[]} 1:{3 : Col[]}]}
func RewriteOp ¶
func RewriteOp[A any](rewriteHandler func(node A) (A, bool)) Optic[Void, A, A, mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, Pure]
RewriteOp constructs a rewrite operation.
See:
- Rewrite for more details.
- RewriteOp for a non index aware version
- RewriteOpI for an index aware version
- RewriteOpE for an error raising version
- RewriteOpIE for an index aware error raising version
func RewriteOpE ¶
func RewriteOpE[A any](rewriteHandler func(ctx context.Context, node A) (A, bool, error)) Optic[Void, A, A, mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, Err]
RewriteOpE constructs an error raising rewrite operation.
See:
- Rewrite for more details.
- RewriteOp for a non index aware version
- RewriteOpI for an index aware version
- RewriteOpE for an error raising version
- RewriteOpIE for an index aware error raising version
func RewriteOpI ¶
func RewriteOpI[I, A any](rewriteHandler func(index *PathNode[I], node A) (A, bool)) Optic[Void, ValueI[*PathNode[I], A], ValueI[*PathNode[I], A], mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, Pure]
RewriteOpI constructs an index aware rewrite operation.
See:
- RewriteI for more details.
- RewriteOp for a non index aware version
- RewriteOpI for an index aware version
- RewriteOpE for an error raising version
- RewriteOpIE for an index aware error raising version
func RewriteOpIE ¶
func RewriteOpIE[I, A any](rewriteHandler func(ctx context.Context, index *PathNode[I], node A) (A, bool, error)) Optic[Void, ValueI[*PathNode[I], A], ValueI[*PathNode[I], A], mo.Option[A], mo.Option[A], ReturnOne, ReadOnly, UniDir, Err]
RewriteOpIE constructs an index aware error raising rewrite operation.
See:
- RewriteOp for a non index aware version
- RewriteOpI for an index aware version
- RewriteOpE for an error raising version
- RewriteOpIE for an index aware error raising version
func TopDown ¶
func TopDown[I, A any, RET, RW, DIR, ERR any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, ERR]
TopDown is a [Traversal] that walks the tree in a top down order. During the traversal the child index is used to construct a path represented as a PathNode
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,C,D See: - TopDownFiltered for a filtering version. - BottomUp for a bottom up version - BreadthFirst for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
optic := TopDown(
children,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B C D]
func TopDownFiltered ¶
func TopDownFiltered[I, A, RET, RW, DIR, ERR, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred Predicate[A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, CompositionTree[ERR, ERRP]]
TopDownFiltered is a [Traversal] that walks the tree in a top down order and filters out branches that don't match the predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is also applied to the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,C,D See: - TopDownFilteredI for an index aware predicate version. - TopDownMatch for a version that performs a match instead of filter.. - TopDown for a simpler non filtering version. - BottomUpFiltered for a bottom up version - BreadthFirstFiltered for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose(
OTree[int, string, Pure]().Value(),
Ne("FilterMe"),
)
optic := TopDownFiltered(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B C D]
func TopDownFilteredI ¶
func TopDownFilteredI[I, A, RET, RW, DIR, ERR any, ERRP any](children Optic[I, A, A, A, A, RET, RW, DIR, ERR], pred PredicateI[*PathNode[I], A, ERRP]) Optic[*PathNode[I], A, A, A, A, ReturnMany, RW, UniDir, CompositionTree[ERR, ERRP]]
TopDownFilteredI is a [Traversal] that walks the tree in a top down order and filters out branches that don't match the index aware predicate. During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is also applied to the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,C,D See: - TopDownFiltered for a simpler non index aware predicate version. - TopDownMatchI for a version that performs a match instead of a filter - TopDown for a simpler non filtering version. - BottomUpFilteredI for a bottom up version - BreadthFirstFilteredI for a breadth first version
Example ¶
tree := Tree(
"A",
ValCol(
Tree(
"B",
ValCol(
Tree("C"),
Tree("FilterMe"),
),
),
Tree("D"),
),
)
children := TraverseTreeChildren[int, string, Pure]()
pred := Compose3(
ValueIIndex[*PathNode[int], TreeNode[int, string, Pure]](),
EqPath(Path(0, 1), EqT2[int]()),
Not(),
)
optic := TopDownFilteredI(
children,
pred,
)
res := MustGet(
SliceOf(
Compose(
optic,
TreeValue[int, string, Pure](),
),
5,
),
tree,
)
fmt.Println(res)
Output: [A B C D]
func TopDownMatch ¶
func TopDownMatch[I, S, RET any, RW any, DIR any, ERR, MERR any](children Optic[I, S, S, S, S, RET, RW, DIR, ERR], matcher Predicate[S, MERR]) Optic[*PathNode[I], S, S, S, S, ReturnMany, RW, UniDir, ERR]
TopDownMatch is a [Traversal] that walks the tree in a top down order and focuses only branches that match the predicate. The top down walk ends at a matching branch.
During the traversal the child index is used to construct a path represented as a PathNode
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,C,D See: - TopDownMatchI for an index aware version - TopDownFilteredI for an version that filters instead of matches. - TopDown for a simpler non filtering version. - BottomUpFiltered for a bottom up version - BreadthFirstFiltered for a breadth first version
Example ¶
data := Tree(
":=",
ValCol(
Tree("x"),
Tree("+",
ValCol(
Tree("1"),
Tree("2"),
),
),
),
)
//Match + nodes
matchAdd := Compose(
OTree[int, string, Pure]().Value(),
Eq("+"),
)
//TopDownMatch will find all matching sub trees
deepAdd := TopDownMatch(
TraverseTreeChildren[int, string, Pure](),
matchAdd,
)
var result []TreeNode[int, string, Pure] = MustGet(SliceOf(deepAdd, 10), data)
fmt.Println(result)
var modifyResult TreeNode[int, string, Pure]
modifyResult, err := Set(
Compose(
deepAdd,
TreeValue[int, string, Pure](),
),
"-",
data,
)
fmt.Println(modifyResult, err)
Output: [{+ : Col[0:{1 : Col[]} 1:{2 : Col[]}]}] {:= : Col[0:{x : Col[]} 1:{- : Col[0:{1 : Col[]} 1:{2 : Col[]}]}]} <nil>
func TopDownMatchI ¶
func TopDownMatchI[I, S, RET any, RW any, DIR any, ERR, MERR any](children Optic[I, S, S, S, S, RET, RW, DIR, ERR], matcher PredicateI[*PathNode[I], S, MERR]) Optic[*PathNode[I], S, S, S, S, ReturnMany, RW, UniDir, ERR]
TopDownMatchI is a [Traversal] that walks the tree in a top down order and focuses only branches that match the index aware predicate. The top down walk ends at a matching branch.
During the traversal the child index is used to construct a path represented as a PathNode
Note: the predicate is also applied to the root node which may result in no tree elements being focused.
In a tree with this structure
+-A +-B | +-C +-D
The elements will be focused in the order A,B,C,D See: - TopDownMatch for a simpler non index aware predicate version. - TopDownFilteredI for a version that performs a filter instead of a match - TopDown for a simpler non filtering version. - BottomUpFilteredI for a bottom up version - BreadthFirstFilteredI for a breadth first version
func TraversePath ¶
func TraverseTreeChildren ¶
func TraverseTreeChildrenI ¶
func TraverseTreeChildrenP ¶
func TreeChildren ¶
func TreeChildren[I, A, ERR any]() Optic[Void, TreeNode[I, A, ERR], TreeNode[I, A, ERR], Collection[I, TreeNode[I, A, ERR], ERR], Collection[I, TreeNode[I, A, ERR], ERR], ReturnOne, ReadWrite, UniDir, Pure]
TreeChildren returns a [Lens] that focuses the direct children of a TreeNode
See:
- [TreeChildrenP] for a polymorphic version.
func TreeValue ¶
func TreeValue[I, A, ERR any]() Optic[Void, TreeNode[I, A, ERR], TreeNode[I, A, ERR], A, A, ReturnOne, ReadWrite, UniDir, Pure]
TreeChildren returns a [Lens] that focuses the direct children of a TreeNode
See:
- [TreeChildrenP] for a polymorphic version.
Example ¶
data := Tree[string](
"Root",
ValCol(
Tree("Leaf 1"),
Tree("Leaf 2"),
),
)
var result string = MustGet(TreeValue[int, string, Pure](), data)
fmt.Println(result)
modifyResult := MustSet(TreeValue[int, string, Pure](), "New Root", data)
fmt.Println(modifyResult)
Output: Root {New Root : Col[0:{Leaf 1 : Col[]} 1:{Leaf 2 : Col[]}]}
func WithChildPath ¶
func WithChildPath[I comparable, S, A any, RET any, RW, DIR, ERR any](o Optic[*PathNode[I], S, S, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR]) Optic[*PathNode[I], S, S, Collection[*PathNode[I], A, ERR], Collection[*PathNode[I], A, ERR], RET, RW, UniDir, ERR]
WithChildPath returns a Traversal that reindexes a [Collection] to a PathNode
See:
- WithChildPathI for a version that supports arbitrary index types
func WithChildPathI ¶
func WithChildPathI[I, S, A any, RET any, RW, DIR, ERR any](o Optic[*PathNode[I], S, S, Collection[I, A, ERR], Collection[I, A, ERR], RET, RW, DIR, ERR], ixMatch func(a, b I) bool) Optic[*PathNode[I], S, S, Collection[*PathNode[I], A, ERR], Collection[*PathNode[I], A, ERR], RET, RW, UniDir, ERR]
WithChildPath returns a Traversal that reindexes a [Collection] to a PathNode
See:
- WithChildPath for a simpler version that supports only comparable index types.
Types ¶
type PathNode ¶
type PathNode[I any] struct { // contains filtered or unexported fields }
type TreeNode ¶
type TreeNode[I, T, ERR any] struct { // contains filtered or unexported fields }
TreeNode is a data structure representing a tree. A TreeNode has a value and a list of child trees.
See:
- Tree for the constructor for this type.
func Tree ¶
func Tree[T any](value T, children ...Collection[int, TreeNode[int, T, Pure], Pure]) TreeNode[int, T, Pure]
Tree is the constructor for TreeNode
See:
- Tree for a version that supports arbitrary index types.
Example ¶
data := Tree[string](
"Root",
ValCol(
Tree("Leaf 1"),
Tree("Leaf 2"),
),
)
fmt.Println(data)
Output: {Root : Col[0:{Leaf 1 : Col[]} 1:{Leaf 2 : Col[]}]}
func TreeIE ¶
func TreeIE[I any, T any, ERR any](value T, ixMatch func(a, b I) bool, children ...Collection[I, TreeNode[I, T, ERR], ERR]) TreeNode[I, T, ERR]
TreeIE is a constructor for TreeNode
See:
- Tree for a simpler version that supports only comparable index types.