diff --git a/src/iter/CCKList.ml b/src/iter/CCKList.ml index 0db8582e..042dba39 100644 --- a/src/iter/CCKList.ml +++ b/src/iter/CCKList.ml @@ -62,6 +62,11 @@ let is_empty l = match l () with | `Nil -> true | `Cons _ -> false +let head_exn l = match l() with | `Nil -> raise Not_found | `Cons (x, _) -> x +let head l = match l() with `Nil -> None | `Cons (x, _) -> Some x +let tail_exn l = match l() with | `Nil -> raise Not_found | `Cons (_, l) -> l +let tail l = match l() with | `Nil -> None | `Cons (_, l) -> Some l + let rec equal eq l1 l2 = match l1(), l2() with | `Nil, `Nil -> true | `Nil, _ @@ -85,6 +90,15 @@ let rec iter f l = match l () with | `Nil -> () | `Cons (x, l') -> f x; iter f l' +let iteri f l = + let rec aux f l i = match l() with + | `Nil -> () + | `Cons (x, l') -> + f i x; + aux f l' (i+1) + in + aux f l 0 + let length l = fold (fun acc _ -> acc+1) 0 l let rec take n (l:'a t) () = match l () with @@ -121,6 +135,18 @@ let rec map f l () = match l () with (map ((+) 1) (1 -- 5) |> to_list) = (2 -- 6 |> to_list) *) +let mapi f l = + let rec aux f l i () = match l() with + | `Nil -> `Nil + | `Cons (x, tl) -> + `Cons (f i x, aux f tl (i+1)) + in + aux f l 0 + +(*$T + mapi (fun i x -> i,x) (1 -- 3) |> to_list = [0, 1; 1, 2; 2, 3] +*) + let rec fmap f (l:'a t) () = match l() with | `Nil -> `Nil | `Cons (x, l') -> @@ -149,6 +175,7 @@ let rec cycle l () = append l (cycle l) () (*$T cycle (of_list [1;2]) |> take 5 |> to_list = [1;2;1;2;1] + cycle (of_list [1; ~-1]) |> take 100_000 |> fold (+) 0 = 0 *) let rec unfold f acc () = match f acc with diff --git a/src/iter/CCKList.mli b/src/iter/CCKList.mli index 9f107017..564bdb79 100644 --- a/src/iter/CCKList.mli +++ b/src/iter/CCKList.mli @@ -64,6 +64,24 @@ val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t val is_empty : 'a t -> bool +val head : 'a t -> 'a option +(** Head of the list + @since NEXT_RELEASE *) + +val head_exn : 'a t -> 'a +(** Unsafe version of {!head} + @raise Not_found if the list is empty + @since NEXT_RELEASE *) + +val tail : 'a t -> 'a t option +(** Tail of the list + @since NEXT_RELEASE *) + +val tail_exn : 'a t -> 'a t +(** Unsafe version of {!tail} + @raise Not_found if the list is empty + @since NEXT_RELEASE *) + val equal : 'a equal -> 'a t equal (** Equality step by step. Eager. *) @@ -75,7 +93,14 @@ val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a val iter : ('a -> unit) -> 'a t -> unit +val iteri : (int -> 'a -> unit) -> 'a t -> unit +(** Iterate with index (starts at 0) + @since NEXT_RELEASE *) + val length : _ t -> int +(** Number of elements in the list. + Will not terminate if the list if infinite: + use (for instance) {!take} to make the list finite if necessary. *) val take : int -> 'a t -> 'a t @@ -87,6 +112,10 @@ val drop_while : ('a -> bool) -> 'a t -> 'a t val map : ('a -> 'b) -> 'a t -> 'b t +val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t +(** Map with index (starts at 0) + @since NEXT_RELEASE *) + val fmap : ('a -> 'b option) -> 'a t -> 'b t val filter : ('a -> bool) -> 'a t -> 'a t @@ -197,5 +226,9 @@ val of_gen : 'a gen -> 'a t (** {2 IO} *) val pp : ?sep:string -> 'a printer -> 'a t printer +(** Print the list with the given separator (default ","). + Does not print opening/closing delimiters *) val print : ?sep:string -> 'a formatter -> 'a t formatter +(** Print the list with the given separator (default ","). + Does not print opening/closing delimiters *)