module splitend

Mutable LIFO stacks safely share immutable data between themselves.

Class SplitEnds

LIFO stacks safely sharing immutable data.

  • each SplitEnd is a very simple stateful (mutable) LIFO stack

  • data can be either “extended” to or “snipped” off the “end”

  • “root” of a SplitEnd is embedded in a scalp

    • the root data is immutable

    • it cannot be split off

  • different mutable split ends can safely share the same “tail”

  • each SplitEnd sees itself as a singularly linked list

  • bush-like datastructures can be formed using multiple SplitEnds

  • the SplitEnd.split and len methods are O(1)

  • in a boolean context

    • falsy just a “root”

    • truthy otherwise

class pythonic_fp.splitends.splitend.SplitEnd

Bases: Generic

__init__(*ds: D, root: SENode | _Sentinel = _sentinel) None

init

param root_data:

Irremovable initial data at bottom of stack.

param ds:

Removable data to be pushed onto splitend stack.

__iter__() Iterator

iter

Iterate from end to root.

yields:

data from end to root

__reversed__() Iterator

reverse iter

Iterate from end to root.

yields:

data from end to root

__bool__() bool

bool

returns:

True if SplitEnd is not just its root node.

__len__() int

len

returns:

The number of nodes on the Splitend.

__eq__(other: object, /) bool

equality comparison

Efficiently compare two SplitEnds.

returns:

True only if other is also a Splitend whose corresponding data to self compares as equal and both share the same root node. Otherwise False.

__repr__() str

repr string

Construct string to reproduce the SplitEnd. TODO: Fix, does not include root node.

returns:

String to reproduce the SplitEnd.

__str__() str

user string

Construct string meaningful to an end user. Does not give root node info.

returns:

String to reproduce the SplitEnd.

snip() D

cut just tip

returns:

Data from snipped tip, just return root data if at root.

cut(num: int | None = None) tuple[D, ...]

Cut data off end of SplitEnd

Pop “cut” data off Split, just copy root data.

param num:

Optional number of nodes to cut, default is entire stack.

returns:

Tuple of data cut off from end towards root.

extend(*ds: D) None

extend SplitEnd with data

Add data onto the tip of the SplitEnd. Like adding a hair extension.

param ds:

data to extend the splitend

peak() D

peak at end

Return the data at end (top) of the SplitEnd without consuming it.

returns:

The data at the end (tip) of the SplitEnd.

root() SENode

get root

returns:

The root SENode node of the SplitEnd.

reroot(root: SENode) SplitEnd[D]

re-root SplitEnd

Create a brand new SplitEnd with the same data but different root.

returns:

New SplitEnd with the same data and the new root.

raises ValueError:

If new and original root nodes are not compatible.

Note

Two nodes are compatible root nodes if and only if

  • they are both actually root nodes

  • which implies that their previous nodes are themselves

  • their data compare as equal

  • comparing by identity is too strong

split(*ds: D) SplitEnd[D]

split

Split the end and add more data.

returns:

New instance, same data nodes plus additional ones on end. Same root node.

fold(f: Callable[[D, D], D]) D
fold(f: Callable[[T, D], T], init: T) T

fold

Reduce with a function, folding from tip to root.

param f:

Folding function, first argument is for the accumulator.

param init:

Optional initial starting value for the fold.

returns:

Reduced value folding from tip to root in natural LIFO order.

rev_fold(f: Callable[[D, D], D]) D
rev_fold(f: Callable[[T, D], T], init: T) T

reverse fold

Reduce with a function, fold from root to tip.

param f:

Folding function, first argument is for the accumulator.

param init:

Optional initial starting value for the fold.

returns:

Reduced value folding from root to tip.