From 0b2c183dbf275fbca3f9e0522cc583f85edccab5 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 22 Jan 2024 23:44:14 +0100 Subject: refactor: naming convention in zipper Unless specified otherwise: - "before" and "left" mean "before the cursor"; - "right" mean "after (and including) the cursor"; - "after" mean "after (i.e., excluding) the cursor". --- lib/zipper.mli | 125 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 55 deletions(-) (limited to 'lib/zipper.mli') diff --git a/lib/zipper.mli b/lib/zipper.mli index e25d57b..d79604e 100644 --- a/lib/zipper.mli +++ b/lib/zipper.mli @@ -35,17 +35,14 @@ val before : 'a zipper -> 'a Sequence.t (** Return the sequence before the cursor *) val after : 'a zipper -> 'a Sequence.t -(** Return the sequence after the cursor *) +(** Return the sequence after (and including) the cursor *) val focus : 'a zipper -> 'a option (** Return the focus of the zipper, if any. *) -val focus_or : 'a zipper -> default:'a -> 'a +val focus_or : default:'a -> 'a zipper -> 'a (** Return the focus of the zipper, or a user-provided default, otherwise. *) -val history : 'a zipper -> 'a Sequence.t -(** Returns the sequence of elements [pop]ped so far from the zipper. *) - val is_far_left : 'a zipper -> bool (** Return whether the cursor is at the beginning of the zipper. *) @@ -109,43 +106,52 @@ val goto : int -> 'a zipper -> 'a zipper This involve [push]ing and [pop]ping elements before and after the cursor. *) -val pop_after : 'a zipper -> 'a zipper -(** Remove the element at the cursor position, if any, and return the - modified zipper. Calling [pop_after z], +val pop : ?n:int -> 'a zipper -> 'a zipper +(** Remove [n] elements at the cursor position (1 by default), if any, + and return the modified zipper. Calling [pop z], - - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [5])], + - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [5])], - if [z] is [([1; 2; 3], [])], the result is [([1; 2; 3], [])]. *) -val pop_before : 'a zipper -> 'a zipper -(** Remove the element before the cursor, if any, and return the - modified zipper. Calling [pop_before z], +val pop_before : ?n:int -> 'a zipper -> 'a zipper +(** Remove [n] elements before the cursor (1 by default), if any, and + return the modified zipper. Calling [pop_before z], - - if [z] is [([3; 2; 1], [4; 5])], the result is [([2; 1], [4, 5])], + - if [z] is [([3; 2; 1], [4; 5])], the result is [([2; 1], [4, 5])], - if [z] is [([], [1; 2; 3])], the result is [([], [1; 2; 3])]. *) -val pop : 'a zipper -> 'a zipper -(** [pop] is an alias for [pop_before]. *) +val pop_after : ?n:int -> 'a zipper -> 'a zipper +(** Remove [n] elements after (and {b not} including) the cursor + (1 by default), if any, and return the modified zipper. + Calling [pop_after z], + + - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [4])], + - if [z] is [([1; 2; 3], [4])], the result is [([1; 2; 3], [4])]. + *) + +val push : 'a -> 'a zipper -> 'a zipper +(** Insert an element at the cursor position. + Calling [push 0 z], if [z] is [([3; 2; 1], [4; 5])], + the result is [([3; 2; 1], [0; 4; 5]))], *) val push_after : 'a -> 'a zipper -> 'a zipper -(** Insert an element after the cursor. +(** Insert an element after the cursor. Behaves like {!Zipper.push} if + the cursor is at the far right of the zipper. Calling [push_after 0 z], if [z] is [([3; 2; 1], [4; 5])], - the result is [([3; 2; 1], [0; 4, 5]))], *) + the result is [([3; 2; 1], [4; 0; 5]))], *) val push_before : 'a -> 'a zipper -> 'a zipper (** Insert an element before the cursor. Return the modified zipper. Calling [push_before 0 z], if [z] is [([3; 2; 1], [4; 5])], - the result is [([0; 3; 2; 1], [4, 5]))]. *) - -val push : 'a -> 'a zipper -> 'a zipper -(** [push] is an alias for [push_before]. *) + the result is [([0; 3; 2; 1], [4; 5]))]. *) val split : 'a zipper -> 'a zipper * 'a zipper (** [split z] splits the zipper in two. [([3; 2; 1], [4; 5])] becomes [([3; 2; 1], []), ([], [4; 5])]. *) -val join : 'a zipper -> 'a zipper -> 'a zipper +val join : 'a zipper -> z2:'a zipper -> 'a zipper (** [join z1 z2] creates a new zipper using [before z1] and [after z2]. [([3; 2; 1], []) ([4; 2], [4; 5])] becomes [([3; 2; 1], [4; 5])]. *) @@ -156,16 +162,16 @@ val join : 'a zipper -> 'a zipper -> 'a zipper Unless otherwise stated, these functions will iterate on the elements before the cursor, first. *) -val iter_before : ('a -> unit) -> 'a zipper -> unit -(** [iter_before f z] will call [f x] for all [x], elements before the +val iter_left : ('a -> unit) -> 'a zipper -> unit +(** [iter_left f z] will call [f x] for all [x], elements before the cursor in [z].*) -val iter_after : ('a -> unit) -> 'a zipper -> unit -(** [iter_after f z] will call [f x] for all [x], elements after the - cursor in [z].*) +val iter_right : ('a -> unit) -> 'a zipper -> unit +(** [iter_right f z] will call [f x] for all [x], elements after (in + including) the cursor in [z]. *) val iter : ('a -> unit) -> 'a zipper -> unit -(** [iter f z] is equivalent to [iter_before f z; iter_after f z] *) +(** [iter f z] is equivalent to [iter_left f z; iter_right f z] *) val for_all : ('a -> bool) -> 'a zipper -> bool (** [for_all p z] tests whether a predicate [p] is [true] for all @@ -175,25 +181,33 @@ val exists : ('a -> bool) -> 'a zipper -> bool (** [exists p z] tests whether at least one element in the zipper is [true] according to the predicate [p]. *) -val find_before : ('a -> bool) -> 'a zipper -> 'a option -(** [find_before p z] will return the first element before the cursor in +val find_left : ('a -> bool) -> 'a zipper -> 'a option +(** [find_left p z] will return the first element before the cursor in [z] satisfying the predicate [p], if any. *) -val find_after : ('a -> bool) -> 'a zipper -> 'a option -(** [find_after p z] will return the first element after the cursor in +val find_right : ('a -> bool) -> 'a zipper -> 'a option +(** [find_right p z] will return the first element after the cursor in [z] satisfying the predicate [p], if any. *) +val apply_focus : ('a -> 'b) -> 'a zipper -> 'b option +(** [apply focus f z] applies f to the current focus, if any, and + returns its result *) + +val apply_focus_or : default:'b -> ('a -> 'b) -> 'a zipper -> 'b +(** [apply focus f z] applies f to the current focus and returns its + result. Return a default value if no element is in focus. *) + (** {1 Transforming zippers} *) (** Since zippers are based on sequences, the functions in this section are lazy; i.e., resulting elements of the zipper are computed only when demanded. *) -val map_before : ('a -> 'a) -> 'a zipper -> 'a zipper +val map_left : ('a -> 'a) -> 'a zipper -> 'a zipper (** Map a function over all elements before the cursor. *) -val map_after : ('a -> 'a) -> 'a zipper -> 'a zipper -(** Map a function over all elements after the cursor. *) +val map_right : ('a -> 'a) -> 'a zipper -> 'a zipper +(** Map a function over all elements after (and including) the cursor. *) val map_focus : ('a -> 'a) -> 'a zipper -> 'a zipper (** Map a function over the element focused by the cursor, if any. *) @@ -202,31 +216,31 @@ val map_focus_or : default:'a -> ('a -> 'a) -> 'a zipper -> 'a zipper (** Map a function over the element focused by the cursor. Push [default] if no element is focused. *) -val map : ('a -> 'a) -> 'a zipper -> 'a zipper +val map : ('a -> 'b) -> 'a zipper -> 'b zipper (** Map a function over all elements of a zipper. *) -val mapi_before : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper -(** [mapi_before] is analogous to {!Zipper.map_before}, but the function +val mapi_left : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper +(** [mapi_left] is analogous to {!Zipper.map_left}, but the function takes an index and an element. The index indicates the distance of an element from the cursor. *) -val mapi_after : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper -(** [mapi_after] is analogous to {!Zipper.map_after}, but the function +val mapi_right : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper +(** [mapi_right] is analogous to {!Zipper.map_right}, but the function takes an index and an element. The index indicates the distance of an element from the cursor. *) -val mapi : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper +val mapi : (int -> 'a -> 'b) -> 'a zipper -> 'b zipper (** [mapi] is analogous to {!Zipper.map}, but the function takes an index and an element. The index indicates the distance of an element from the cursor. *) -val filter_before : ('a -> bool) -> 'a zipper -> 'a zipper -(** [filter_before p z] filters the elements before the cursor in a +val filter_left : ('a -> bool) -> 'a zipper -> 'a zipper +(** [filter_left p z] filters the elements before the cursor in a zipper [z] according to a predicate [p], i.e., keeping the elements that satisfy the predicate. *) -val filter_after : ('a -> bool) -> 'a zipper -> 'a zipper -(** [filter_after p z] filters the elements after the cursor in a +val filter_right : ('a -> bool) -> 'a zipper -> 'a zipper +(** [filter_right p z] filters the elements after the cursor in a zipper [z] according to a predicate [p], i.e., keeping the elements that satisfy the predicate. *) @@ -235,21 +249,22 @@ val filter : ('a -> bool) -> 'a zipper -> 'a zipper predicate [p], i.e., keeping the elements that satisfy the predicate. *) -val context_before : int -> 'a zipper -> 'a zipper -(** [context_before n z] will limit the zipper [z] to [n] elements before +val context_left : int -> 'a zipper -> 'a zipper +(** [context_left n z] will limit the zipper [z] to [n] elements before the cursor. *) -val context_after : int -> 'a zipper -> 'a zipper -(** [context_after n z] will limit the zipper [z] to [n] elements after +val context_right : int -> 'a zipper -> 'a zipper +(** [context_right n z] will limit the zipper [z] to [n] elements after the cursor. *) -val context : b:int -> ?a:int -> 'a zipper -> 'a zipper -(** [context ~b ~a z] will limit the zipper [z] to [b] elements before - the cursor and [a] elements after the cursor. When [a] is not - provided, it defaults to [b]. *) +val context : l:int -> ?r:int -> 'a zipper -> 'a zipper +(** [context ~l ~r z] will limit the zipper [z] to [l] elements before + the cursor and [r] elements after the cursor. When [r] is not + provided, it defaults to [l]. *) -val clear_history : 'a zipper -> 'a zipper -(** Clear the history of the zipper. See {!Zipper.history}. *) +val swap_focus : 'a -> 'a zipper -> 'a zipper +(** Swap the element in focus with a newly provided element. Nothing + happens if no element is in focus. *) (** {1 Zippers and sequences} *) -- cgit v1.2.3