# View Source ExRoseTree.Zipper (ExRoseTree v0.1.3)

A context-aware zipper for advanced traversal and manipulation of an `ExRoseTree`

.

Accompanying the `Zipper`

are a large number of both navigation primitives and more complex
traversal functions built out of said primitives. An attempt has been made at providing
semantically meaningful names for these primitives, drawing from gender-neutral, familial
taxonomy (with a few liberties taken in creating neolisms to better suit the domain here),
with the aim of establishing a sort of *navigational pattern language*.

The words `first`

, `last`

, `next`

, and `previous`

are ubiquitous and commonly paired with
the likes of `child`

, `sibling`

, `pibling`

(non-binary form of aunt/uncle), `nibling`

(non-binary form of niece/nephew), and `cousin`

to label specific navigation primitives.
Other, less common words used for more specialized navigations include `ancestral`

, `descendant`

,
and `extended`

.

Care has been taken to make naming conventions reflect the expected operations as closely as possible, though there are a few cases where it might not be entirely obvious, particularly for some of the more specialized operations, so be sure to read the documentation closely and test for your use case when using a navigational function for the first time.

Many of these functions take an optional `predicate()`

function which can be used to perform a
navigational function until said predicate is satisfied. For example, `ExRoseTree.Zipper.first_sibling(zipper, &(&1.term == 5))`

will search, starting from the 0-th (first) index, the list of siblings that occur *before but not after*
the current context for the first occurrence of a sibling with a `term`

value equal to `5`

. If
none are found, the context will not have been moved, and the function returns `nil`

. Note, the
predicate function will default to `Util.always/1`

, which always returns `true`

. When using the default
predicate (in essence, not using a predicate) with this example, `ExRoseTree.Zipper.first_sibling(zipper)`

,
the function will simply move the context to the first sibling of the initial context. If the are no
previous siblings, it will return `nil`

.

In general, most of the navigation primitives take constant time, while mutation is done at the current position and is a local operation.

# Link to this section Summary

## Types

The `Zipper`

struct represents a contextual position within an `ExRoseTree`

.

## Basic Functionality

Returns the current focus of the `Zipper`

.

Returns the depth (as zero-based index) of the current focus.

Returns an empty `Zipper`

.

Returns the children of the `Zipper`

's current focus.

Returns the `term`

of the current focus of the `Zipper`

.

Builds a new `Zipper`

from a list of `ExRoseTree.Zipper.Location`

s.

Returns the index (zero-based) of the current focus with respect to any potential siblings it may have.

Applies the given function to the current focus.

Applies the given function to the focused children of the current focus.

Applies the given function to the `term`

of the current focus.

Applies the given function to path of `ExRoseTree.Zipper.Location`

s from the current focus back to the root
without moving the `Zipper`

.

Returns a new `Zipper`

with its focus on the given `ExRoseTree`

.
Optionally take a list of previous and next sibling trees when
using the `:prev`

and `:next`

keyword options.

Builds a new `ExRoseTree.Zipper.Location`

out of the current `Zipper`

.

Removes the current focus and then moves the focus to one of three places

Returns whether or not the current `Zipper`

is at the root of the tree.
A `Zipper`

is considered at the root when it has no `ExRoseTree.Zipper.Location`

s in its path.

Sets the current focus of the `Zipper`

to the given `ExRoseTree`

.

Sets the focused children to the given list of rose trees.

Sets the `term`

of the current focus of the `Zipper`

.

Moves a `Zipper`

back to the root and returns a 2-tuple containing first, a
list containing the previous siblings to the original root and second, a list
containing the original root followed by its `next`

siblings.

Moves a `Zipper`

back to the root and returns the current focus, the root `ExRoseTree`

.

## Common Traversal

Accumulates an additional value using the provided `acc_fn()`

while traversing the
`Zipper`

using the provided `move_fn()`

. Returns a tuple including the new `Zipper`

context and the accumulated value.

Using the given `move_fn()`

, searches for the first
tree that satisfies the given `predicate`

function.

Traverses the `Zipper`

using the provided `move_fn()`

and maps the `term`

at each node using the provided `map_fn()`

. Returns the new `Zipper`

with
mapped values.

Repeats a call to the given `move_fn()`

, by the
given number of `reps`

.

Moves a direction in the `Zipper`

, determined by the `move_fn()`

, if
and only if the provided predicate function returns `true`

when applied
to the next node. Otherwise, returns `nil`

.

Continuously moves a direction in the `Zipper`

, determined by the `move_fn()`

,
until the provided predicate function returns `true`

when applied to the next
node. Otherwise, returns `nil`

.

Repeats the given `move_fn()`

while the given predicate remains `true`

.
If no custom predicate is given, the `move_fn()`

will repeat until it no
longer can.

## Path Traversal

Rewinds the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the root `Zipper`

and the accumulated value.

Searches for a predicate match by rewinding the path in the `Zipper`

. If no match
is found, returns `nil`

.

Rewinds a `Zipper`

along the `path`

by the given number of `reps`

.

Rewinds a `Zipper`

along the `path`

if the provided predicate function
returns `true`

when applied to the parent node. Otherwise, returns `nil`

.

Rewinds the `Zipper`

and maps the `term`

at each node using the provided `map_fn()`

.
Returns the new `Zipper`

at the root with mapped values.

Rewinds a `Zipper`

back to the root.

Rewinds a `Zipper`

continuously until the provided predicate function
returns `true`

when applied to the next parent node. Otherwise, returns `nil`

.

Rewinds a `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `parent/1`

will repeat until it reaches the root.

## Breadth-first Traversal

Traverses backward through the `Zipper`

in a breadth-first manner.

Moves backward in the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by moving backward in the `Zipper`

. If no match
is found, returns `nil`

.

Repeats a call to `backward/1`

by the given number of `reps`

.

Moves backward in the `Zipper`

if the provided predicate function
returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves backward in the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Moves backward through the `Zipper`

until the root has been reached. If the
root has previous siblings, will move the the first sibling of the root.

Moves backward in the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves backward in the `Zipper`

while the given predicate remains `true`

.
If no custom predicate is given, `backward/1`

will repeat until it no
longer can.

Traverses forward through the `Zipper`

in a breadth-first manner.

Moves forward in the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by moving forward in the `Zipper`

. If no match
is found, returns `nil`

.

Repeats a call to `forward/1`

by the given number of `reps`

.

Moves forward in the `Zipper`

if the provided predicate function
returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves forward in the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Moves forward through the `Zipper`

until the last node of the tree
has been reached.

Moves forward in the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves forward in the `Zipper`

while the given predicate remains `true`

.
If no custom predicate is given, `forward/1`

will repeat until it no
longer can.

## Depth-first Traversal

Traverses back through the `Zipper`

in a depth-first manner.

Ascends the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by ascending the `Zipper`

. If no match
is found, returns `nil`

.

Repeats a call to `ascend/1`

by the given number of `reps`

.

Ascends the `Zipper`

if the provided predicate function returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Ascends the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Ascends the `Zipper`

until the root has been reached. If the root has
previous siblings, will move the the first sibling of the root.

Ascends the `Zipper`

continuously until the provided predicate function
returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Ascends the `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `ascend/1`

will repeat until it no longer can.

Traverses forward through the `Zipper`

in a depth-first manner.

Descends the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by descending the `Zipper`

. If no match
is found, returns `nil`

.

Repeats a call to `descend/1`

by the given number of `reps`

.

Descends into the `Zipper`

if the provided predicate function
returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Descends the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Descends the `Zipper`

until the last node of the tree has been reached.

Descends into the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next focus. Otherwise,
returns `nil`

.

Descends the `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `descend/1`

will repeat until it no longer can.

## Direct Ancestors

Moves the focus to the grandparent -- the parent of the parent -- of
the focus, if possible. If there is no grandparent, returns `nil`

.

Moves the focus to the great-grandparent -- parent of the grand-parent -- of
the focus, if available. If there is no great-grandparent, returns `nil`

.

Returns the index (zero-based) of the current focus' grandparent with
respect to any potentital siblings it may have. If the current
focus has no grandparent, returns `nil`

.

Returns the index (zero-based) of the current focus' parent with
respect to any potentital siblings it may have. If the current
focus has no parent, returns `nil`

.

Moves the focus to the parent `ExRoseTree.Zipper.Location`

. If at the root, thus no
parent, returns `nil`

.

Returns the current `Zipper`

's parent `ExRoseTree.Zipper.Location`

.

Returns the `term`

in the current `Zipper`

's parent `ExRoseTree.Zipper.Location`

.

## Direct Descendants

Moves focus to the child at the specified index. If there are no children,
or if the child does not exist at the index, returns `nil`

.

Moves focus to the first child. If there are no children, and this is
a leaf, returns `nil`

.

Moves the focus to the first grandchild -- the first child of the
first child -- of the focus. If there are no grandchildren, moves to
the next sibling of the first child and looks for that tree's first
child. This repeats until the first grandchild is found or it returns
`nil`

if none are found.

Moves the focus to the first great-grandchild -- the first child of the
first grandchild -- of the focus. If there are no great-grandchildren, moves to
the next sibling of the first grandchild and looks for that tree's first
child. This repeats until the first great-grandchild is found or it returns
`nil`

if none are found.

Moves focus to the last child. If there are no children, and this is
a leaf, returns `nil`

.

Moves the focus to the last grandchild -- the last child of the
last child -- of the focus. If there are no grandchildren, moves to
the previous sibling of the last child and looks for that tree's last
child. This repeats until the first grandchild is found or it returns
`nil`

if none are found.

Moves the focus to the last great-grandchild -- the last child of the
last grandchild -- of the focus. If there are no great-grandchildren,
moves to the previous sibling of the last grandchild and looks for that tree's
last child. This repeats until the last great-grandchild is found or it
returns `nil`

if none are found.

Descend the left-most edge until it can go no further or until the optional predicate matches. Does not include siblings of starting focus.

Descend the right-most edge until it can go no further or until the optional predicate matches. Does not include siblings of starting focus.

## Siblings

Appends a new sibling to the `Zipper`

's `next`

siblings.

Appends a new sibling to the `Zipper`

's `prev`

siblings.

Moves focus to the first sibling from the current focus. If there are
no more siblings before the current focus, returns `nil`

.

Inserts a new sibling in the `Zipper`

's `next`

siblings at the given index.

Inserts a new sibling in the `Zipper`

's `prev`

siblings at the given index.

Moves focus to the last sibling from the current focus. If there are
no more siblings after the current focus, returns `nil`

.

Applies the given function to all `next`

siblings of the current focus without
moving the `Zipper`

.

Applies the given function to all previous siblings of the current focus without
moving the `Zipper`

.

Moves focus to the next sibling of the current focus. If there are
no more siblings after the current focus, returns `nil`

.

Returns the siblings that come after the current focus.

Removes the first sibling from the `Zipper`

.

Removes the last sibling from the `Zipper`

.

Removes the next sibling from the `Zipper`

.

Removes a sibling from the `Zipper`

's `next`

siblings at the given index.

Removes the previous sibling from the `Zipper`

.

Removes a sibling from the `Zipper`

's `prev`

siblings at the given index.

Prepends a new sibling to the Ziper's `prev`

siblings.

Prepends a new sibling to the `Zipper`

's `next`

siblings.

Moves focus to the previous sibling to the current focus. If there are
no more siblings before the current focus, returns `nil`

.

Returns the siblings that come before the current focus.

Moves focus to the sibling of the current focus at the given index.
If no sibling is found at that index, or if the provided index
is the index for the current focus, returns `nil`

.

## Niblings: Nieces & Nephews

Recursively searches the descendant branches of the first sibling for the first "descendant nibling" of the current focus. That is, if a first nibling is found, it will then look for the first child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

Searches for the first child of the first extended cousin--aka, the first extended nibling--of the focused tree.

Moves the focus to the first nibling -- the first child of the
first sibling with children -- before the current focus. If not
found, returns `nil`

.

Moves the focus to the first nibling for a specific sibling -- the
first child of the sibling at the given index -- of the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the last sibling for the last "descendant nibling" of the current focus. That is, if a last nibling is found, it will then look for the last child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

Searches for the last child of the last extended cousin--aka, the last extended nibling--of the focused tree.

Moves the focus to the last nibling -- the last child of the
last sibling with children -- before the current focus. If not
found, returns `nil`

.

Moves the focus to the last nibling for a specific sibling -- the
last child of the sibling at the given index -- of the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the next sibling for the next "descendant nibling" of the current focus. That is, if a next nibling is found, it will then look for the first child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

Searches for the first child of the next extended cousin--aka, the next extended nibling--of the focused tree.

Moves the focus to the next grand-nibling -- the first grandchild of
the next sibling -- of the current focus. If not found, returns `nil`

.

Moves the focus to the next nibling -- the first child of the
first next sibling with children -- before the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the previous sibling for the previous "descendant nibling" of the current focus. That is, if a previous nibling is found, it will then look for the last child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

Searches for the last child of the previous extended cousin--aka, the previous extended nibling--of the focused tree.

Moves the focus to the previous grand-nibling -- the last grandchild of
the previous sibling -- of the current focus. If not found, returns `nil`

.

Moves the focus to the previous nibling -- the last child of the
first previous sibling with children -- before the current focus.
If not found, returns `nil`

.

## Piblings: Aunts & Uncles

Recursively searches the `path`

for the first, first "ancestral" pibling. That is,
if a first pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a first pibling,
the function returns `nil`

.

Searches for the first extended cousin of the parent--aka, the first extended pibling--of the focused tree.

Moves the focus to the first grandpibling -- the first sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

Moves the focus to the first pibling -- the first sibling of the parent --
of the current focus. If not found, returns `nil`

.

Recursively searches the `path`

for the first, last "ancestral" pibling. That is,
if a last pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a last pibling,
the function returns `nil`

.

Searches for the last extended cousin of the parent--aka, the last extended pibling--of the focused tree.

Moves the focus to the last grandpibling -- the last sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

Moves the focus to the last pibling -- the last sibling of the parent --
of the current focus. If not found, returns `nil`

.

Recursively searches the `path`

for the first, next "ancestral" pibling. That is,
if a next pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a next pibling,
the function returns `nil`

.

Searches for the next extended cousin of the parent--aka, the next extended pibling--of the focused tree.

Moves the focus to the next grandpibling -- the next sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

Moves the focus to the next pibling -- the next sibling of the parent --
of the current focus. If not found, returns `nil`

.

Moves the focus to the pibling of the current focus at the given index.
If no pibling is found at that index, returns `nil`

.

Recursively searches the `path`

for the first, previous "ancestral" pibling. That is,
if a previous pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a previous pibling,
the function returns `nil`

.

Searches for the previous extended cousin of the parent--aka, the previous extended pibling--of the focused tree.

Moves the focus to the previous grandpibling -- the previous sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

Moves the focus to the previous pibling -- the previous sibling of the parent --
of the current focus. If not found, returns `nil`

.

## First Cousins

Moves the focus to the first first-cousin -- the first child of the first
pibling with children -- of the current focus. If not found, returns `nil`

.

Moves the focus to the last first-cousin -- the last child of the last
pibling with children -- of the current focus. If not found, returns `nil`

.

Moves the focus to the next first-cousin -- the first child of the
next pibling with children -- of the current focus. If not found, returns `nil`

.

Moves the focus to the previous first-cousin -- the last child of the
previous pibling with children -- of the current focus. If not found, returns `nil`

.

## Second Cousins

Moves the focus to the first second-cousin -- the first grandchild of
the first grandpibling with grandchildren -- of the current focus. If not
found, returns `nil`

.

Moves the focus to the last second-cousin -- the last grandchild of
the last grandpibling with grandchildren -- of the current focus. If not
found, returns `nil`

.

Moves the focus to the next second-cousin -- the first grandchild of the
next grandpibling with grandchildren -- of the current focus. If not found, returns `nil`

.

Moves the focus to the previous second-cousin -- the last grandchild of the
previous grandpibling with grandchildren -- of the current focus. If not found, returns `nil`

.

## Extended Cousins

Searches for the first extended cousin or the first first-cousin of the focused tree.

Searches for the last extended cousin or the last first-cousin of the focused tree.

Searches for the next extended cousin or the next first-cousin of the focused tree.

Searches for the previous extended cousin or the previous first-cousin of the focused tree.

# Link to this section Types

@type t() :: %ExRoseTree.Zipper{ focus: ExRoseTree.t(), next: [ExRoseTree.t()], path: [ExRoseTree.Zipper.Location.t()], prev: [ExRoseTree.t()] }

The `Zipper`

struct represents a contextual position within an `ExRoseTree`

.

It includes the following important pieces:

`focus`

- the current*focus*or*context*within the`ExRoseTree.Zipper`

. Its type is that of an`ExRoseTree`

.`prev`

- all siblings occurring before the current`focus`

. It's type is a list of`ExRoseTree`

s and is maintained in reverse order, so that the immediately previous sibling to the`focus`

is at the head of the list.`next`

- all siblings occurring after the current`focus`

. It's type is a list of`ExRoseTree`

s and is maintained in standard order.`path`

- all direct ancestors of the the current`focus`

back to the root node. It's type is a list of`ExRoseTree.Zipper.Location`

s and is maintained in standard order. If the`path`

is an empty list, then the`Zipper`

is focused at the root node.

# Link to this section Guards

# Link to this section Basic Functionality

@spec current_focus(t()) :: ExRoseTree.t()

Returns the current focus of the `Zipper`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.current_focus(z)
%ExRoseTree{term: 5, children: []}
```

@spec depth_of_focus(t()) :: non_neg_integer()

Returns the depth (as zero-based index) of the current focus.

##
examples

Examples

```
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: locs)
...> ExRoseTree.Zipper.depth_of_focus(z)
4
```

@spec empty() :: t()

Returns an empty `Zipper`

.

##
examples

Examples

```
iex> ExRoseTree.Zipper.empty()
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: nil, children: []},
prev: [],
next: [],
path: []
}
```

@spec focused_children(t()) :: [ExRoseTree.t()]

Returns the children of the `Zipper`

's current focus.

A shortcut to `ExRoseTree.get_children/1`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [1,2,3,4])
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.focused_children(z)
[
%ExRoseTree{term: 1, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 4, children: []}
]
```

Returns the `term`

of the current focus of the `Zipper`

.

A shortcut to using `ExRoseTree.get_term/1`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.focused_term(z)
5
```

@spec from_locations([ExRoseTree.Zipper.Location.t()]) :: t()

Builds a new `Zipper`

from a list of `ExRoseTree.Zipper.Location`

s.

##
examples

Examples

```
iex> locs = for loc <- [3,2,1], do: ExRoseTree.Zipper.Location.new(loc)
...> ExRoseTree.Zipper.from_locations(locs)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 3, children: []},
prev: [],
next: [],
path: [
%ExRoseTree.Zipper.Location{
prev: [],
term: 2,
next: []
},
%ExRoseTree.Zipper.Location{
prev: [],
term: 1,
next: []
}
]
}
```

@spec index_of_focus(t()) :: non_neg_integer()

Returns the index (zero-based) of the current focus with respect to any potential siblings it may have.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev)
...> ExRoseTree.Zipper.index_of_focus(z)
4
```

@spec map_focus(t(), (ExRoseTree.t() -> ExRoseTree.t())) :: t()

Applies the given function to the current focus.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> map_fn = &ExRoseTree.set_children(&1, [6,7,8,9])
...> ExRoseTree.Zipper.map_focus(z, &map_fn.(&1))
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: [
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []},
]},
prev: [],
next: [],
path: []
}
```

@spec map_focused_children(t(), (ExRoseTree.t() -> ExRoseTree.t())) :: t()

Applies the given function to the focused children of the current focus.

A shortcut to `ExRoseTree.map_children/2`

and `set_focus/2`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [1,2,3,4])
...> z = ExRoseTree.Zipper.new(tree)
...> map_fn = &ExRoseTree.map_term(&1, fn x -> x * 2 end)
...> ExRoseTree.Zipper.map_focused_children(z, map_fn)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: [
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 8, children: []}
]},
prev: [],
next: [],
path: []
}
```

Applies the given function to the `term`

of the current focus.

A shortcut to using `ExRoseTree.map_term/2`

with `set_focus/2`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> map_fn = fn term -> term * 2 end
...> ExRoseTree.Zipper.map_focused_term(z, &map_fn.(&1))
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 10, children: []},
prev: [],
next: [],
path: []
}
```

@spec map_path( t(), (ExRoseTree.Zipper.Location.t() -> ExRoseTree.Zipper.Location.t()) ) :: t()

Applies the given function to path of `ExRoseTree.Zipper.Location`

s from the current focus back to the root
without moving the `Zipper`

.

##
examples

Examples

```
iex> path = for n <- [4,3,2,1], do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: path)
...> map_fn = &ExRoseTree.Zipper.Location.map_term(&1, fn term -> term * 2 end)
...> ExRoseTree.Zipper.map_path(z, &map_fn.(&1))
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [],
next: [],
path: [
%ExRoseTree.Zipper.Location{prev: [], term: 8, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 6, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 4, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 2, next: []}]
}
```

@spec new( ExRoseTree.t(), keyword() ) :: t()

Returns a new `Zipper`

with its focus on the given `ExRoseTree`

.
Optionally take a list of previous and next sibling trees when
using the `:prev`

and `:next`

keyword options.

Note that a

`Zipper`

maintains the list of previous siblings in reverse order internally, and this function performs that reversal itself, so do not pre-reverse your list of previous siblings when using that option!

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> ExRoseTree.Zipper.new(tree)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [],
next: [],
path: []
}
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> ExRoseTree.Zipper.new(tree, prev: prev)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 1, children: []}
],
next: [],
path: []
}
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> ExRoseTree.Zipper.new(tree, path: locs)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [],
next: [],
path: [
%ExRoseTree.Zipper.Location{prev: [], term: 4, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 3, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 2, next: []},
%ExRoseTree.Zipper.Location{prev: [], term: 1, next: []}
]
}
```

@spec new_location(t()) :: ExRoseTree.Zipper.Location.t()

Builds a new `ExRoseTree.Zipper.Location`

out of the current `Zipper`

.

##
examples

Examples

```
iex> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, next: next)
...> ExRoseTree.Zipper.new_location(z)
%ExRoseTree.Zipper.Location{
prev: [],
term: 5,
next: [
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
]
}
```

@spec remove_focus(t()) :: {t(), ExRoseTree.t() | nil}

Removes the current focus and then moves the focus to one of three places:

- the next sibling, if one exists,
- else the previous sibling, if one exists,
- else the parent, if one exists

If none of those conditions exist, it will return an empty `Zipper`

. In any case,
the new `Zipper`

will be returned as the first item in a tuple, while the removed
focus will be returned as the second item.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> prev_siblings = for n <- [3,4], do: ExRoseTree.new(n)
...> next_siblings = for n <- [6,7], do: ExRoseTree.new(n)
...> z = ExRoseTree.Zipper.new(tree, prev: prev_siblings, next: next_siblings)
...> ExRoseTree.Zipper.remove_focus(z)
{%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 6, children: []},
prev: [
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 3, children: []}
],
next: [
%ExRoseTree{term: 7, children: []}
],
path: []
},
%ExRoseTree{term: 5, children: []}}
```

Returns whether or not the current `Zipper`

is at the root of the tree.
A `Zipper`

is considered at the root when it has no `ExRoseTree.Zipper.Location`

s in its path.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.root?(z)
true
```

@spec set_focus(t(), ExRoseTree.t()) :: t()

Sets the current focus of the `Zipper`

to the given `ExRoseTree`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.empty()
...> ExRoseTree.Zipper.set_focus(z, tree)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [],
next: [],
path: []
}
```

@spec set_focused_children(t(), [ExRoseTree.t()]) :: t()

Sets the focused children to the given list of rose trees.

A shortcut to `ExRoseTree.set_children/2`

and `set_focus/2`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [1,2,3,4])
...> z = ExRoseTree.Zipper.new(tree)
...> new_children = for t <- [6,7,8,9], do: ExRoseTree.new(t)
...> ExRoseTree.Zipper.set_focused_children(z, new_children)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: [
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
]},
prev: [],
next: [],
path: []
}
```

Sets the `term`

of the current focus of the `Zipper`

.

A shortcut to using `ExRoseTree.set_term/2`

with `set_focus/2`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.set_focused_term(z, 10)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 10, children: []},
prev: [],
next: [],
path: []
}
```

@spec to_forest(t()) :: {[ExRoseTree.t()], [ExRoseTree.t()]}

Moves a `Zipper`

back to the root and returns a 2-tuple containing first, a
list containing the previous siblings to the original root and second, a list
containing the original root followed by its `next`

siblings.

##
examples

Examples

```
iex> tree = ExRoseTree.new(3, [6])
...> prev_trees = for t <- [1,2], do: ExRoseTree.new(t)
...> next_trees = for t <- [4,5], do: ExRoseTree.new(t)
...> z = ExRoseTree.Zipper.new(tree, prev: prev_trees, next: next_trees)
...> z = Zipper.last_child(z)
...> Zipper.to_forest(z)
{
[
%ExRoseTree{term: 1, children: []},
%ExRoseTree{term: 2, children: []}
],
[
%ExRoseTree{term: 3, children: [%ExRoseTree{term: 6, children: []}]},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 5, children: []}
]
}
```

@spec to_tree(t()) :: ExRoseTree.t()

Moves a `Zipper`

back to the root and returns the current focus, the root `ExRoseTree`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [1,2,3,4])
...> z = ExRoseTree.Zipper.new(tree)
...> z = Zipper.last_child(z)
...> Zipper.to_tree(z)
%ExRoseTree{
term: 5,
children: [
%ExRoseTree{term: 1, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 4, children: []},
]
}
```

# Link to this section Common Traversal

Accumulates an additional value using the provided `acc_fn()`

while traversing the
`Zipper`

using the provided `move_fn()`

. Returns a tuple including the new `Zipper`

context and the accumulated value.

Using the given `move_fn()`

, searches for the first
tree that satisfies the given `predicate`

function.

Traverses the `Zipper`

using the provided `move_fn()`

and maps the `term`

at each node using the provided `map_fn()`

. Returns the new `Zipper`

with
mapped values.

@spec move_for( t(), move_fn(), pos_integer() ) :: t() | nil

Repeats a call to the given `move_fn()`

, by the
given number of `reps`

.

##
examples

Examples

```
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: locs)
...> move_fn = &ExRoseTree.Zipper.parent/1
...> z = ExRoseTree.Zipper.move_for(z, move_fn, 2)
...> ExRoseTree.Zipper.current_focus(z).term
3
```

Moves a direction in the `Zipper`

, determined by the `move_fn()`

, if
and only if the provided predicate function returns `true`

when applied
to the next node. Otherwise, returns `nil`

.

Continuously moves a direction in the `Zipper`

, determined by the `move_fn()`

,
until the provided predicate function returns `true`

when applied to the next
node. Otherwise, returns `nil`

.

Repeats the given `move_fn()`

while the given predicate remains `true`

.
If no custom predicate is given, the `move_fn()`

will repeat until it no
longer can.

# Link to this section Path Traversal

Rewinds the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the root `Zipper`

and the accumulated value.

Searches for a predicate match by rewinding the path in the `Zipper`

. If no match
is found, returns `nil`

.

@spec rewind_for(t(), pos_integer()) :: t() | nil

Rewinds a `Zipper`

along the `path`

by the given number of `reps`

.

Rewinds a `Zipper`

along the `path`

if the provided predicate function
returns `true`

when applied to the parent node. Otherwise, returns `nil`

.

Rewinds the `Zipper`

and maps the `term`

at each node using the provided `map_fn()`

.
Returns the new `Zipper`

at the root with mapped values.

Rewinds a `Zipper`

back to the root.

##
examples

Examples

```
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: locs)
...> z = ExRoseTree.Zipper.rewind_to_root(z)
...> ExRoseTree.Zipper.root?(z)
true
```

Rewinds a `Zipper`

continuously until the provided predicate function
returns `true`

when applied to the next parent node. Otherwise, returns `nil`

.

Rewinds a `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `parent/1`

will repeat until it reaches the root.

# Link to this section Breadth-first Traversal

Traverses backward through the `Zipper`

in a breadth-first manner.

Moves backward in the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by moving backward in the `Zipper`

. If no match
is found, returns `nil`

.

@spec backward_for(t(), pos_integer()) :: t() | nil

Repeats a call to `backward/1`

by the given number of `reps`

.

Moves backward in the `Zipper`

if the provided predicate function
returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves backward in the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Moves backward through the `Zipper`

until the root has been reached. If the
root has previous siblings, will move the the first sibling of the root.

Moves backward in the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves backward in the `Zipper`

while the given predicate remains `true`

.
If no custom predicate is given, `backward/1`

will repeat until it no
longer can.

Traverses forward through the `Zipper`

in a breadth-first manner.

Moves forward in the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by moving forward in the `Zipper`

. If no match
is found, returns `nil`

.

@spec forward_for(t(), pos_integer()) :: t() | nil

Repeats a call to `forward/1`

by the given number of `reps`

.

Moves forward in the `Zipper`

if the provided predicate function
returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves forward in the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Moves forward through the `Zipper`

until the last node of the tree
has been reached.

Moves forward in the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next node. Otherwise, returns `nil`

.

Moves forward in the `Zipper`

while the given predicate remains `true`

.
If no custom predicate is given, `forward/1`

will repeat until it no
longer can.

# Link to this section Depth-first Traversal

Traverses back through the `Zipper`

in a depth-first manner.

Ascends the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by ascending the `Zipper`

. If no match
is found, returns `nil`

.

@spec ascend_for(t(), pos_integer()) :: t() | nil

Repeats a call to `ascend/1`

by the given number of `reps`

.

Ascends the `Zipper`

if the provided predicate function returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Ascends the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Ascends the `Zipper`

until the root has been reached. If the root has
previous siblings, will move the the first sibling of the root.

Ascends the `Zipper`

continuously until the provided predicate function
returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Ascends the `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `ascend/1`

will repeat until it no longer can.

Traverses forward through the `Zipper`

in a depth-first manner.

Descends the `Zipper`

and accumulates an additional value using the provided
`acc_fn()`

. Returns a tuple including the new `Zipper`

and the accumulated value.

Searches for a predicate match by descending the `Zipper`

. If no match
is found, returns `nil`

.

@spec descend_for(t(), pos_integer()) :: t() | nil

Repeats a call to `descend/1`

by the given number of `reps`

.

Descends into the `Zipper`

if the provided predicate function
returns `true`

when applied to the next focus. Otherwise, returns `nil`

.

Descends the `Zipper`

and maps the `term`

at each node using the provided
`map_fn()`

. Returns the new `Zipper`

with mapped values.

Descends the `Zipper`

until the last node of the tree has been reached.

Descends into the `Zipper`

continuously until the provided predicate
function returns `true`

when applied to the next focus. Otherwise,
returns `nil`

.

Descends the `Zipper`

while the given predicate remains `true`

. If no custom
predicate is given, `descend/1`

will repeat until it no longer can.

# Link to this section Direct Ancestors

Moves the focus to the grandparent -- the parent of the parent -- of
the focus, if possible. If there is no grandparent, returns `nil`

.

Moves the focus to the great-grandparent -- parent of the grand-parent -- of
the focus, if available. If there is no great-grandparent, returns `nil`

.

@spec index_of_grandparent(t()) :: non_neg_integer() | nil

Returns the index (zero-based) of the current focus' grandparent with
respect to any potentital siblings it may have. If the current
focus has no grandparent, returns `nil`

.

##
examples

Examples

```
iex> grandparent_siblings = for n <- [3,2,1], do: ExRoseTree.new(n)
...> grandparent_loc = ExRoseTree.Zipper.Location.new(4, prev: grandparent_siblings)
...> parent_loc = ExRoseTree.Zipper.Location.new(5)
...> tree = ExRoseTree.new(6)
...> z = ExRoseTree.Zipper.new(tree, path: [parent_loc, grandparent_loc])
...> ExRoseTree.Zipper.index_of_grandparent(z)
3
```

@spec index_of_parent(t()) :: non_neg_integer() | nil

Returns the index (zero-based) of the current focus' parent with
respect to any potentital siblings it may have. If the current
focus has no parent, returns `nil`

.

##
examples

Examples

```
iex> parent_siblings = for n <- [3,2,1], do: ExRoseTree.new(n)
...> parent_loc = ExRoseTree.Zipper.Location.new(4, prev: parent_siblings)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: [parent_loc])
...> ExRoseTree.Zipper.index_of_parent(z)
3
```

Moves the focus to the parent `ExRoseTree.Zipper.Location`

. If at the root, thus no
parent, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [3,4], do: ExRoseTree.new(n)
...> loc_trees = for n <- [2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, path: locs)
...> ExRoseTree.Zipper.parent(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{
term: 2,
children: [
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 5, children: []}
]
},
prev: [],
next: [],
path: [%ExRoseTree.Zipper.Location{prev: [], term: 1, next: []}]
}
```

@spec parent_location(t()) :: ExRoseTree.Zipper.Location.t() | nil

Returns the current `Zipper`

's parent `ExRoseTree.Zipper.Location`

.

##
examples

Examples

```
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: locs)
...> ExRoseTree.Zipper.parent_location(z)
%ExRoseTree.Zipper.Location{prev: [], term: 4, next: []}
```

@spec parent_term(t()) :: ExRoseTree.t() | nil

Returns the `term`

in the current `Zipper`

's parent `ExRoseTree.Zipper.Location`

.

##
examples

Examples

```
iex> loc_trees = for n <- [4,3,2,1], do: ExRoseTree.new(n)
...> locs = for n <- loc_trees, do: ExRoseTree.Zipper.Location.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, path: locs)
...> ExRoseTree.Zipper.parent_term(z)
4
```

# Link to this section Direct Descendants

@spec child_at(t(), non_neg_integer()) :: t() | nil

Moves focus to the child at the specified index. If there are no children,
or if the child does not exist at the index, returns `nil`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [6,7,8,9])
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.child_at(z, 2)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 8, children: []},
prev: [
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 6, children: []}
],
next: [%ExRoseTree{term: 9, children: []}],
path: [%ExRoseTree.Zipper.Location{prev: [], term: 5, next: []}]
}
```

@spec first_child(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the first child. If there are no children, and this is
a leaf, returns `nil`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [6,7,8,9])
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.first_child(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 6, children: []},
prev: [],
next: [
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
],
path: [%ExRoseTree.Zipper.Location{prev: [], term: 5, next: []}]
}
iex> tree = ExRoseTree.new(5, [6,7,8,9])
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.first_child(z, fn x -> x.term == 9 end)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 9, children: []},
prev: [
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 6, children: []}
],
next: [],
path: [%ExRoseTree.Zipper.Location{prev: [], term: 5, next: []}]
}
```

@spec first_grandchild(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first grandchild -- the first child of the
first child -- of the focus. If there are no grandchildren, moves to
the next sibling of the first child and looks for that tree's first
child. This repeats until the first grandchild is found or it returns
`nil`

if none are found.

@spec first_great_grandchild(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first great-grandchild -- the first child of the
first grandchild -- of the focus. If there are no great-grandchildren, moves to
the next sibling of the first grandchild and looks for that tree's first
child. This repeats until the first great-grandchild is found or it returns
`nil`

if none are found.

@spec last_child(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the last child. If there are no children, and this is
a leaf, returns `nil`

.

##
examples

Examples

```
iex> tree = ExRoseTree.new(5, [6,7,8,9])
...> z = ExRoseTree.Zipper.new(tree)
...> ExRoseTree.Zipper.last_child(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 9, children: []},
prev: [
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 6, children: []}
],
next: [],
path: [%ExRoseTree.Zipper.Location{prev: [], term: 5, next: []}]
}
```

@spec last_grandchild(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last grandchild -- the last child of the
last child -- of the focus. If there are no grandchildren, moves to
the previous sibling of the last child and looks for that tree's last
child. This repeats until the first grandchild is found or it returns
`nil`

if none are found.

@spec last_great_grandchild(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last great-grandchild -- the last child of the
last grandchild -- of the focus. If there are no great-grandchildren,
moves to the previous sibling of the last grandchild and looks for that tree's
last child. This repeats until the last great-grandchild is found or it
returns `nil`

if none are found.

Descend the left-most edge until it can go no further or until the optional predicate matches. Does not include siblings of starting focus.

Descend the right-most edge until it can go no further or until the optional predicate matches. Does not include siblings of starting focus.

# Link to this section Siblings

Appends a new sibling to the `Zipper`

's `next`

siblings.

Appends a new sibling to the `Zipper`

's `prev`

siblings.

@spec first_sibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the first sibling from the current focus. If there are
no more siblings before the current focus, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, next: next)
...> ExRoseTree.Zipper.first_sibling(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 1, children: []},
prev: [],
next: [
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 5, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
],
path: []
}
```

Inserts a new sibling in the `Zipper`

's `next`

siblings at the given index.

Inserts a new sibling in the `Zipper`

's `prev`

siblings at the given index.

@spec last_sibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the last sibling from the current focus. If there are
no more siblings after the current focus, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, next: next)
...> ExRoseTree.Zipper.last_sibling(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 9, children: []},
prev: [
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 5, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 1, children: []}
],
next: [],
path: []
}
```

@spec map_next_siblings(t(), (ExRoseTree.t() -> ExRoseTree.t())) :: t()

Applies the given function to all `next`

siblings of the current focus without
moving the `Zipper`

.

##
examples

Examples

```
iex> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, next: next)
...> map_fn = &ExRoseTree.map_term(&1, fn term -> term * 2 end)
...> ExRoseTree.Zipper.map_next_siblings(z, &map_fn.(&1))
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [],
next: [
%ExRoseTree{term: 12, children: []},
%ExRoseTree{term: 14, children: []},
%ExRoseTree{term: 16, children: []},
%ExRoseTree{term: 18, children: []}
],
path: []
}
```

@spec map_previous_siblings(t(), (ExRoseTree.t() -> ExRoseTree.t())) :: t()

Applies the given function to all previous siblings of the current focus without
moving the `Zipper`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev)
...> map_fn = &ExRoseTree.map_term(&1, fn term -> term * 2 end)
...> ExRoseTree.Zipper.map_previous_siblings(z, &map_fn.(&1))
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 5, children: []},
prev: [
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 2, children: []}
],
next: [],
path: []
}
```

@spec next_sibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the next sibling of the current focus. If there are
no more siblings after the current focus, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, next: next)
...> ExRoseTree.Zipper.next_sibling(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 6, children: []},
prev: [
%ExRoseTree{term: 5, children: []},
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 1, children: []}
],
next: [
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
],
path: []
}
```

@spec next_siblings(t()) :: [ExRoseTree.t()]

Returns the siblings that come after the current focus.

##
examples

Examples

```
iex> next = for t <- [6,7,8,9], do: ExRoseTree.new(t)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, next: next)
...> ExRoseTree.Zipper.next_siblings(z)
[
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
]
```

@spec pop_first_sibling(t()) :: {t(), ExRoseTree.t() | nil}

Removes the first sibling from the `Zipper`

.

@spec pop_last_sibling(t()) :: {t(), ExRoseTree.t() | nil}

Removes the last sibling from the `Zipper`

.

@spec pop_next_sibling(t()) :: {t(), ExRoseTree.t() | nil}

Removes the next sibling from the `Zipper`

.

@spec pop_next_sibling_at(t(), integer()) :: {t(), ExRoseTree.t() | nil}

Removes a sibling from the `Zipper`

's `next`

siblings at the given index.

@spec pop_previous_sibling(t()) :: {t(), ExRoseTree.t() | nil}

Removes the previous sibling from the `Zipper`

.

@spec pop_previous_sibling_at(t(), integer()) :: {t(), ExRoseTree.t() | nil}

Removes a sibling from the `Zipper`

's `prev`

siblings at the given index.

Prepends a new sibling to the Ziper's `prev`

siblings.

Prepends a new sibling to the `Zipper`

's `next`

siblings.

@spec previous_sibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves focus to the previous sibling to the current focus. If there are
no more siblings before the current focus, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, next: next)
...> ExRoseTree.Zipper.previous_sibling(z)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 4, children: []},
prev: [
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 1, children: []}
],
next: [
%ExRoseTree{term: 5, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
],
path: []
}
```

@spec previous_siblings(t()) :: [ExRoseTree.t()]

Returns the siblings that come before the current focus.

##
examples

Examples

```
iex> prev = for t <- [1,2,3,4], do: ExRoseTree.new(t)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev)
...> ExRoseTree.Zipper.previous_siblings(z)
[
%ExRoseTree{term: 1, children: []},
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 3, children: []},
%ExRoseTree{term: 4, children: []}
]
```

@spec sibling_at(t(), non_neg_integer()) :: t() | nil

Moves focus to the sibling of the current focus at the given index.
If no sibling is found at that index, or if the provided index
is the index for the current focus, returns `nil`

.

##
examples

Examples

```
iex> prev = for n <- [1,2,3,4], do: ExRoseTree.new(n)
...> next = for n <- [6,7,8,9], do: ExRoseTree.new(n)
...> tree = ExRoseTree.new(5)
...> z = ExRoseTree.Zipper.new(tree, prev: prev, next: next)
...> ExRoseTree.Zipper.sibling_at(z, 2)
%ExRoseTree.Zipper{
focus: %ExRoseTree{term: 3, children: []},
prev: [
%ExRoseTree{term: 2, children: []},
%ExRoseTree{term: 1, children: []}
],
next: [
%ExRoseTree{term: 4, children: []},
%ExRoseTree{term: 5, children: []},
%ExRoseTree{term: 6, children: []},
%ExRoseTree{term: 7, children: []},
%ExRoseTree{term: 8, children: []},
%ExRoseTree{term: 9, children: []}
],
path: []
}
```

# Link to this section Niblings: Nieces & Nephews

Recursively searches the descendant branches of the first sibling for the first "descendant nibling" of the current focus. That is, if a first nibling is found, it will then look for the first child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

@spec first_extended_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the first child of the first extended cousin--aka, the first extended nibling--of the focused tree.

@spec first_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first nibling -- the first child of the
first sibling with children -- before the current focus. If not
found, returns `nil`

.

# first_nibling_at_sibling(zipper, index, predicate \\ &Util.always/1)

View Source@spec first_nibling_at_sibling(t(), non_neg_integer(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first nibling for a specific sibling -- the
first child of the sibling at the given index -- of the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the last sibling for the last "descendant nibling" of the current focus. That is, if a last nibling is found, it will then look for the last child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

@spec last_extended_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the last child of the last extended cousin--aka, the last extended nibling--of the focused tree.

@spec last_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last nibling -- the last child of the
last sibling with children -- before the current focus. If not
found, returns `nil`

.

# last_nibling_at_sibling(zipper, index, predicate \\ &Util.always/1)

View Source@spec last_nibling_at_sibling(t(), non_neg_integer(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last nibling for a specific sibling -- the
last child of the sibling at the given index -- of the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the next sibling for the next "descendant nibling" of the current focus. That is, if a next nibling is found, it will then look for the first child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

@spec next_extended_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the first child of the next extended cousin--aka, the next extended nibling--of the focused tree.

@spec next_grandnibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next grand-nibling -- the first grandchild of
the next sibling -- of the current focus. If not found, returns `nil`

.

@spec next_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next nibling -- the first child of the
first next sibling with children -- before the current focus.
If not found, returns `nil`

.

Recursively searches the descendant branches of the previous sibling for the previous "descendant nibling" of the current focus. That is, if a previous nibling is found, it will then look for the last child of that tree (the "descendant nibling"). It will repeat the search if one is found, and it will continue until no more are found, returning the last one visited.

@spec previous_extended_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the last child of the previous extended cousin--aka, the previous extended nibling--of the focused tree.

@spec previous_grandnibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous grand-nibling -- the last grandchild of
the previous sibling -- of the current focus. If not found, returns `nil`

.

@spec previous_nibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous nibling -- the last child of the
first previous sibling with children -- before the current focus.
If not found, returns `nil`

.

# Link to this section Piblings: Aunts & Uncles

@spec first_ancestral_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Recursively searches the `path`

for the first, first "ancestral" pibling. That is,
if a first pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a first pibling,
the function returns `nil`

.

@spec first_extended_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the first extended cousin of the parent--aka, the first extended pibling--of the focused tree.

Note: Extended Pibling here really means parent-cousin n-times removed, and is a bit of a neolism, since pibling technically means parent-sibling.

@spec first_grandpibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first grandpibling -- the first sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

@spec first_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first pibling -- the first sibling of the parent --
of the current focus. If not found, returns `nil`

.

@spec last_ancestral_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Recursively searches the `path`

for the first, last "ancestral" pibling. That is,
if a last pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a last pibling,
the function returns `nil`

.

@spec last_extended_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the last extended cousin of the parent--aka, the last extended pibling--of the focused tree.

Note: Extended Pibling here really means parent-cousin n-times removed, and is a bit of a neolism, since pibling technically means parent-sibling.

@spec last_grandpibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last grandpibling -- the last sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

@spec last_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last pibling -- the last sibling of the parent --
of the current focus. If not found, returns `nil`

.

@spec next_ancestral_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Recursively searches the `path`

for the first, next "ancestral" pibling. That is,
if a next pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a next pibling,
the function returns `nil`

.

@spec next_extended_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the next extended cousin of the parent--aka, the next extended pibling--of the focused tree.

Note: Extended Pibling here really means parent-cousin n-times removed, and is a bit of a neolism, since pibling technically means parent-sibling.

@spec next_grandpibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next grandpibling -- the next sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

@spec next_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next pibling -- the next sibling of the parent --
of the current focus. If not found, returns `nil`

.

@spec pibling_at(t(), non_neg_integer()) :: t() | nil

Moves the focus to the pibling of the current focus at the given index.
If no pibling is found at that index, returns `nil`

.

@spec previous_ancestral_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Recursively searches the `path`

for the first, previous "ancestral" pibling. That is,
if a previous pibling is not found for the parent, it will search the grandparent. If
one is not found for the grandparent, it will search the great-grandparent. And so on,
until it reaches the root. If the root is reached and it does not have a previous pibling,
the function returns `nil`

.

@spec previous_extended_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the previous extended cousin of the parent--aka, the previous extended pibling--of the focused tree.

@spec previous_grandpibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous grandpibling -- the previous sibling of the grandparent --
of the current focus. If not found, returns `nil`

.

@spec previous_pibling(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous pibling -- the previous sibling of the parent --
of the current focus. If not found, returns `nil`

.

# Link to this section First Cousins

@spec first_first_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first first-cousin -- the first child of the first
pibling with children -- of the current focus. If not found, returns `nil`

.

@spec last_first_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last first-cousin -- the last child of the last
pibling with children -- of the current focus. If not found, returns `nil`

.

@spec next_first_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next first-cousin -- the first child of the
next pibling with children -- of the current focus. If not found, returns `nil`

.

@spec previous_first_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous first-cousin -- the last child of the
previous pibling with children -- of the current focus. If not found, returns `nil`

.

# Link to this section Second Cousins

@spec first_second_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the first second-cousin -- the first grandchild of
the first grandpibling with grandchildren -- of the current focus. If not
found, returns `nil`

.

@spec last_second_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the last second-cousin -- the last grandchild of
the last grandpibling with grandchildren -- of the current focus. If not
found, returns `nil`

.

@spec next_second_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the next second-cousin -- the first grandchild of the
next grandpibling with grandchildren -- of the current focus. If not found, returns `nil`

.

@spec previous_second_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Moves the focus to the previous second-cousin -- the last grandchild of the
previous grandpibling with grandchildren -- of the current focus. If not found, returns `nil`

.

# Link to this section Extended Cousins

@spec first_extended_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the first extended cousin or the first first-cousin of the focused tree.

High level steps:

- Ascend
`path`

to find highest`ExRoseTree.Zipper.Location`

with`prev`

siblings. - Starting with the first sibling, check each subtree from left to right, and if you reach the target depth and find a tree that satisifies any given predicate, stop there. Otherwise, continue left to right.
- If you return back to the starting
`ExRoseTree.Zipper.Location`

, descend the`path`

to next deepest`ExRoseTree.Zipper.Location`

and set as starting`ExRoseTree.Zipper.Location`

. Goto step 2. - If you return back to starting
`ExRoseTree.Zipper.Location`

, and it is also the ending`ExRoseTree.Zipper.Location`

, and you have not found a suitable note at the right depth, you will not find one.

@spec last_extended_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the last extended cousin or the last first-cousin of the focused tree.

@spec next_extended_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the next extended cousin or the next first-cousin of the focused tree.

@spec previous_extended_cousin(t(), ExRoseTree.predicate()) :: t() | nil

Searches for the previous extended cousin or the previous first-cousin of the focused tree.