diff options
| author | Federico Igne <undyamon@disroot.org> | 2024-01-28 23:41:50 +0100 |
|---|---|---|
| committer | Federico Igne <undyamon@disroot.org> | 2024-01-28 23:41:50 +0100 |
| commit | 633fb26ed21f7208517aa29dbaab9f0cf3bb2047 (patch) | |
| tree | 2b6ae4402b61a03886f527355a9b480900598bdf /lib/tipper.mli | |
| parent | 05e1cc51b2fb0824580925b55319377305105c44 (diff) | |
| download | sandy-633fb26ed21f7208517aa29dbaab9f0cf3bb2047.tar.gz sandy-633fb26ed21f7208517aa29dbaab9f0cf3bb2047.zip | |
feat: add generic tree zipper data structure
Diffstat (limited to 'lib/tipper.mli')
| -rw-r--r-- | lib/tipper.mli | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/tipper.mli b/lib/tipper.mli new file mode 100644 index 0000000..f2a8288 --- /dev/null +++ b/lib/tipper.mli | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | open Base | ||
| 2 | |||
| 3 | (** Tree zippers. | ||
| 4 | |||
| 5 | A zipper represents {b a paused traversal} of a certain data | ||
| 6 | structure. A tree zipper of type ['a tipper] represents a zipper | ||
| 7 | over a generic tree of ['a] elements. | ||
| 8 | |||
| 9 | One can access the {b focused element} of the zipper with [focus]. | ||
| 10 | The focus of a zipper is also known as the the {b cursor} of the | ||
| 11 | zipper. The cursor can be moved [up] to the parent node, if any, or | ||
| 12 | [down] to one of the selected children; [left] and [right] can be | ||
| 13 | used to select adjacent children. To select the right (resp. left) | ||
| 14 | sibling of the current cursor, for example, one should go [up], move | ||
| 15 | [right] (resp. [left]) and [down] again. | ||
| 16 | |||
| 17 | Elements can be added to the children of the current cursor with | ||
| 18 | [push] and removed with [pop]. | ||
| 19 | |||
| 20 | In this particular implementation, there is no such thing as an {b | ||
| 21 | empty} tree zipper. *) | ||
| 22 | |||
| 23 | type !+'a tipper | ||
| 24 | (** A zipper is represented as an element of type ['a], a parent ['a | ||
| 25 | tipper] (with a hole) and a sequences of ['a tipper] children. *) | ||
| 26 | |||
| 27 | type !+'a t = 'a tipper | ||
| 28 | (** An alias for the ['a tipper] type. *) | ||
| 29 | |||
| 30 | val create : 'a -> 'a tipper | ||
| 31 | (** [create a] returns a new tipper with a single node containing [a]. *) | ||
| 32 | |||
| 33 | val focus : 'a tipper -> 'a | ||
| 34 | (** Returns the element pointed by the cursor *) | ||
| 35 | |||
| 36 | val is_root : 'a tipper -> bool | ||
| 37 | (** Returns whether the cursor is at the root of the tree. *) | ||
| 38 | |||
| 39 | val is_leaf : 'a tipper -> bool | ||
| 40 | (** Returns whether the cursor is pointing to a leaf (a node with no | ||
| 41 | children). *) | ||
| 42 | |||
| 43 | val is_far_left : 'a tipper -> bool | ||
| 44 | (** Returns whether the leftmost child is selected. *) | ||
| 45 | |||
| 46 | val is_far_right : 'a tipper -> bool | ||
| 47 | (** Returns whether the rightmost child is selected. *) | ||
| 48 | |||
| 49 | (** {1 Moving the cursor} *) | ||
| 50 | |||
| 51 | val left : 'a tipper -> 'a tipper | ||
| 52 | (** Select the children on the left. *) | ||
| 53 | |||
| 54 | val far_left : 'a tipper -> 'a tipper | ||
| 55 | (** Select the children on the far left. *) | ||
| 56 | |||
| 57 | val right : 'a tipper -> 'a tipper | ||
| 58 | (** Select the children on the right. *) | ||
| 59 | |||
| 60 | val far_right : 'a tipper -> 'a tipper | ||
| 61 | (** Select the children on the far right. *) | ||
| 62 | |||
| 63 | val up : 'a tipper -> 'a tipper | ||
| 64 | (** Move cursor to the parent node, if any. *) | ||
| 65 | |||
| 66 | val up_while : f:('a tipper -> bool) -> 'a tipper -> 'a tipper | ||
| 67 | (** [up_while ~f t] moves the cursor in [t] up while the predicate [f] | ||
| 68 | is satisfied. *) | ||
| 69 | |||
| 70 | val root : 'a tipper -> 'a tipper | ||
| 71 | (** Move the cursor up to the root of the tree. *) | ||
| 72 | |||
| 73 | val down : 'a tipper -> 'a tipper | ||
| 74 | (** Move cursor to the selected child node, if any. *) | ||
| 75 | |||
| 76 | (** {1 Modifying the tree zipper} *) | ||
| 77 | |||
| 78 | val set_focus : 'a -> 'a tipper -> 'a tipper | ||
| 79 | (** [set_focus a t] sets the element at the cursor position in [t] to | ||
| 80 | [a]. *) | ||
| 81 | |||
| 82 | val push : 'a tipper -> 'a tipper -> 'a tipper | ||
| 83 | (** [push t1 t2] adds [t1] as a subtree child of the node in [t2] | ||
| 84 | pointed by the cursor, so that [t1] is the newly selected child. *) | ||
| 85 | |||
| 86 | val pop : 'a tipper -> 'a tipper option * 'a tipper | ||
| 87 | (** [pop t] removes the subtree associated with the selected child. | ||
| 88 | Returns the subtree as a first element and the modified [t] as the | ||
| 89 | second. *) | ||
| 90 | |||
| 91 | (** {1 Consuming the tree zipper} *) | ||
| 92 | |||
| 93 | val fold : a:'a -> f:('a -> 'b tipper -> 'a) -> 'b tipper -> 'a | ||
