(* This file is free software, part of containers. See file "license" for more details. *) (** {1 complements to list} *) type 'a t = 'a list val empty : 'a t val is_empty : _ t -> bool (** [is_empty l] returns [true] iff [l = []] @since 0.11 *) val map : ('a -> 'b) -> 'a t -> 'b t (** Safe version of map *) val (>|=) : 'a t -> ('a -> 'b) -> 'b t (** Infix version of [map] with reversed arguments @since 0.5 *) val cons : 'a -> 'a t -> 'a t (** [cons x l] is [x::l] @since 0.12 *) val append : 'a t -> 'a t -> 'a t (** Safe version of append *) val cons_maybe : 'a option -> 'a t -> 'a t (** [cons_maybe (Some x) l] is [x :: l] [cons_maybe None l] is [l] @since 0.13 *) val (@) : 'a t -> 'a t -> 'a t val filter : ('a -> bool) -> 'a t -> 'a t (** Safe version of {!List.filter} *) val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b (** Safe version of [fold_right] *) val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a (** Fold until a stop condition via [('a, `Stop)] is indicated by the accumulator @since 0.8 *) val fold_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a list -> 'acc * 'b list (** [fold_map f acc l] is a [fold_left]-like function, but it also maps the list to another list. @since 0.14 *) val fold_map2 : ('acc -> 'a -> 'b -> 'acc * 'c) -> 'acc -> 'a list -> 'b list -> 'acc * 'c list (** [fold_map2] is to [fold_map] what [List.map2] is to [List.map]. @raise Invalid_argument if the lists do not have the same length @since NEXT_RELEASE *) val fold_flat_map : ('acc -> 'a -> 'acc * 'b list) -> 'acc -> 'a list -> 'acc * 'b list (** [fold_flat_map f acc l] is a [fold_left]-like function, but it also maps the list to a list of lists that is then [flatten]'d.. @since 0.14 *) val init : int -> (int -> 'a) -> 'a t (** Similar to {!Array.init} @since 0.6 *) val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool val flat_map : ('a -> 'b t) -> 'a t -> 'b t (** Map and flatten at the same time (safe). Evaluation order is not guaranteed. *) val flatten : 'a t t -> 'a t (** Safe flatten *) val product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t (** Cartesian product of the two lists, with the given combinator *) val fold_product : ('c -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c (** Fold on the cartesian product *) val diagonal : 'a t -> ('a * 'a) t (** All pairs of distinct positions of the list. [list_diagonal l] will return the list of [List.nth i l, List.nth j l] if [i < j]. *) val partition_map : ('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> 'a list -> 'b list * 'c list (** [partition_map f l] maps [f] on [l] and gather results in lists: - if [f x = `Left y], adds [y] to the first list - if [f x = `Right z], adds [z] to the second list - if [f x = `Drop], ignores [x] @since 0.11 *) val pure : 'a -> 'a t val (<*>) : ('a -> 'b) t -> 'a t -> 'b t val (<$>) : ('a -> 'b) -> 'a t -> 'b t val return : 'a -> 'a t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val take : int -> 'a t -> 'a t (** Take the [n] first elements, drop the rest *) val drop : int -> 'a t -> 'a t (** Drop the [n] first elements, keep the rest *) val hd_tl : 'a t -> 'a * 'a t (** [hd_tl (x :: l)] returns [hd, l]. @raise Failure if the list is empty @since NEXT_RELEASE *) val take_drop : int -> 'a t -> 'a t * 'a t (** [take_drop n l] returns [l1, l2] such that [l1 @ l2 = l] and [length l1 = min (length l) n] *) val take_while : ('a -> bool) -> 'a t -> 'a t (** @since 0.13 *) val drop_while : ('a -> bool) -> 'a t -> 'a t (** @since 0.13 *) val split : int -> 'a t -> 'a t * 'a t (** Synonym to {!take_drop} @deprecated since 0.13: conflict with the {!List.split} standard function *) val last : int -> 'a t -> 'a t (** [last n l] takes the last [n] elements of [l] (or less if [l] doesn't have that many elements *) val find_pred : ('a -> bool) -> 'a t -> 'a option (** [find_pred p l] finds the first element of [l] that satisfies [p], or returns [None] if no element satisfies [p] @since 0.11 *) val find_pred_exn : ('a -> bool) -> 'a t -> 'a (** Unsafe version of {!find_pred} @raise Not_found if no such element is found @since 0.11 *) val find_map : ('a -> 'b option) -> 'a t -> 'b option (** [find_map f l] traverses [l], applying [f] to each element. If for some element [x], [f x = Some y], then [Some y] is returned. Otherwise the call returns [None] @since 0.11 *) val find : ('a -> 'b option) -> 'a list -> 'b option (** @deprecated since 0.11 in favor of {!find_map}, for the name is too confusing *) val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option (** Like {!find_map}, but also pass the index to the predicate function. @since 0.11 *) val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option (** @deprecated since 0.11 in favor of {!find_mapi}, name is too confusing @since 0.3.4 *) val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option (** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], and [p x] holds. Otherwise returns [None] *) val remove : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t (** [remove ~x l] removes every instance of [x] from [l]. Tailrec. @param eq equality function @since 0.11 *) val filter_map : ('a -> 'b option) -> 'a t -> 'b t (** Map and remove elements at the same time *) val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** Merges elements from both sorted list *) val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list (** Sort the list and remove duplicate elements *) val sorted_merge_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** [sorted_merge_uniq l1 l2] merges the sorted lists [l1] and [l2] and removes duplicates @since 0.10 *) val uniq_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list (** [uniq_succ l] removes duplicate elements that occur one next to the other. Examples: [uniq_succ [1;2;1] = [1;2;1]] [uniq_succ [1;1;2] = [1;2]] @since 0.10 *) val group_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list list (** [group_succ ~eq l] groups together consecutive elements that are equal according to [eq] @since 0.11 *) (** {2 Indices} *) module Idx : sig val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t val iteri : (int -> 'a -> unit) -> 'a t -> unit val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b (** Fold on list, with index *) val get : 'a t -> int -> 'a option val get_exn : 'a t -> int -> 'a (** Get the i-th element, or @raise Not_found if the index is invalid *) val set : 'a t -> int -> 'a -> 'a t (** Set i-th element (removes the old one), or does nothing if index is too high *) val insert : 'a t -> int -> 'a -> 'a t (** Insert at i-th position, between the two existing elements. If the index is too high, append at the end of the list *) val remove : 'a t -> int -> 'a t (** Remove element at given index. Does nothing if the index is too high. *) end (** {2 Set Operators} *) module Set : sig val add : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t (** [add x set] adds [x] to [set] if it was not already present. Linear time. @since 0.11 *) val remove : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t (** [remove x set] removes one occurrence of [x] from [set]. Linear time. @since 0.11 *) val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool (** Membership to the list. Linear time *) val subset : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool (** Test for inclusion *) val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t (** List uniq. Remove duplicates w.r.t the equality predicate. Complexity is quadratic in the length of the list, but the order of elements is preserved. If you wish for a faster de-duplication but do not care about the order, use {!sort_uniq}*) val union : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t (** List union. Complexity is product of length of inputs. *) val inter : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t (** List intersection. Complexity is product of length of inputs. *) end (** {2 Other Constructors} *) val range : int -> int -> int t (** [range i j] iterates on integers from [i] to [j] included . It works both for decreasing and increasing ranges *) val range' : int -> int -> int t (** Same as {!range} but the second bound is excluded. For instance [range' 0 5 = [0;1;2;3;4]] *) val (--) : int -> int -> int t (** Infix alias for [range] *) val replicate : int -> 'a -> 'a t (** Replicate the given element [n] times *) val repeat : int -> 'a t -> 'a t (** Concatenate the list with itself [n] times *) (** {2 Association Lists} *) module Assoc : sig type ('a, 'b) t = ('a*'b) list val get : ?eq:('a->'a->bool) -> ('a,'b) t -> 'a -> 'b option (** Find the element *) val get_exn : ?eq:('a->'a->bool) -> ('a,'b) t -> 'a -> 'b (** Same as [get] @raise Not_found if the element is not present *) val set : ?eq:('a->'a->bool) -> ('a,'b) t -> 'a -> 'b -> ('a,'b) t (** Add the binding into the list (erase it if already present) *) val mem : ?eq:('a->'a->bool) -> ('a,_) t -> 'a -> bool (** [mem l x] returns [true] iff [x] is a key in [l] @since NEXT_RELEASE *) val update : ?eq:('a->'a->bool) -> ('a,'b) t -> 'a -> f:('b option -> 'b option) -> ('a,'b) t (** [update l k ~f] updates [l] on the key [k], by calling [f (get l k)] and removing [k] if it returns [None], mapping [k] to [v'] if it returns [Some v'] @since NEXT_RELEASE *) end (** {2 Zipper} *) module Zipper : sig type 'a t = 'a list * 'a list (** The pair [l, r] represents the list [List.rev_append l r], but with the focus on [r]. *) val empty : 'a t (** Empty zipper *) val is_empty : _ t -> bool (** Empty zipper? Returns true iff the two lists are empty. *) (*$T Zipper.(is_empty empty) not ([42] |> Zipper.make |> Zipper.right |> Zipper.is_empty) *) val to_list : 'a t -> 'a list (** Convert the zipper back to a list. [to_list (l,r)] is [List.rev_append l r] *) val to_rev_list : 'a t -> 'a list (** Convert the zipper back to a {i reversed} list. In other words, [to_list (l,r)] is [List.rev_append r l] @since 0.14 *) val make : 'a list -> 'a t (** Create a zipper pointing at the first element of the list *) val left : 'a t -> 'a t (** Go to the left, or do nothing if the zipper is already at leftmost pos *) val left_exn : 'a t -> 'a t (** Go to the left, or @raise Invalid_argument if the zipper is already at leftmost pos @since 0.14 *) val right : 'a t -> 'a t (** Go to the right, or do nothing if the zipper is already at rightmost pos *) val right_exn : 'a t -> 'a t (** Go to the right, or @raise Invalid_argument if the zipper is already at rightmost pos @since 0.14 *) val modify : ('a option -> 'a option) -> 'a t -> 'a t (** Modify the current element, if any, by returning a new element, or returning [None] if the element is to be deleted *) val insert : 'a -> 'a t -> 'a t (** Insert an element at the current position. If an element was focused, [insert x l] adds [x] just before it, and focuses on [x] @since 0.14 *) val remove : 'a t -> 'a t (** [remove l] removes the current element, if any. @since 0.14 *) val is_focused : _ t -> bool (** Is the zipper focused on some element? That is, will {!focused} return a [Some v]? @since 0.14 *) val focused : 'a t -> 'a option (** Returns the focused element, if any. [focused zip = Some _] iff [empty zip = false] *) val focused_exn : 'a t -> 'a (** Returns the focused element, or @raise Not_found if the zipper is at an end *) val drop_before : 'a t -> 'a t (** Drop every element on the "left" (calling {!left} then will do nothing). @since 0.14 *) val drop_after : 'a t -> 'a t (** Drop every element on the "right" (calling {!right} then will do nothing), keeping the focused element, if any. @since 0.14 *) val drop_after_and_focused : 'a t -> 'a t (** Drop every element on the "right" (calling {!right} then will do nothing), {i including} the focused element if it is present. @since 0.14 *) (*$= ([1], [2]) (Zipper.drop_after ([1], [2;3])) ([1], []) (Zipper.drop_after ([1], [])) ([1], []) (Zipper.drop_after_and_focused ([1], [2;3])) *) end (** {2 References on Lists} @since 0.3.3 *) module Ref : sig type 'a t = 'a list ref val push : 'a t -> 'a -> unit val pop : 'a t -> 'a option val pop_exn : 'a t -> 'a (** Unsafe version of {!pop}. @raise Failure if the list is empty *) val create : unit -> 'a t (** Create a new list reference *) val clear : _ t -> unit (** Remove all elements *) val lift : ('a list -> 'b) -> 'a t -> 'b (** Apply a list function to the content *) val push_list : 'a t -> 'a list -> unit (** Add elements of the list at the beginning of the list ref. Elements at the end of the list will be at the beginning of the list ref *) end (** {2 Monadic Operations} *) module type MONAD = sig type 'a t val return : 'a -> 'a t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t end module Traverse(M : MONAD) : sig val sequence_m : 'a M.t t -> 'a t M.t val fold_m : ('b -> 'a -> 'b M.t) -> 'b -> 'a t -> 'b M.t val map_m : ('a -> 'b M.t) -> 'a t -> 'b t M.t val map_m_par : ('a -> 'b M.t) -> 'a t -> 'b t M.t (** Same as {!map_m} but [map_m_par f (x::l)] evaluates [f x] and [f l] "in parallel" before combining their result (for instance in Lwt). *) end (** {2 Conversions} *) type 'a sequence = ('a -> unit) -> unit type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a printer = Buffer.t -> 'a -> unit type 'a formatter = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a val random : 'a random_gen -> 'a t random_gen val random_non_empty : 'a random_gen -> 'a t random_gen val random_len : int -> 'a random_gen -> 'a t random_gen val random_choose : 'a t -> 'a random_gen (** Randomly choose an element in the list. @raise Not_found if the list is empty *) val random_sequence : 'a random_gen t -> 'a t random_gen val to_seq : 'a t -> 'a sequence val of_seq : 'a sequence -> 'a t val to_gen : 'a t -> 'a gen val of_gen : 'a gen -> 'a t val to_klist : 'a t -> 'a klist val of_klist : 'a klist -> 'a t (** {2 IO} *) val pp : ?start:string -> ?stop:string -> ?sep:string -> 'a printer -> 'a t printer val print : ?start:string -> ?stop:string -> ?sep:string -> 'a formatter -> 'a t formatter