Merge pull request #32 from struktured/master

fold_while implementation for CCList and CCArray (fixes #29)
This commit is contained in:
Simon Cruanes 2015-01-01 20:41:50 +01:00
commit b3a38657d1
4 changed files with 53 additions and 3 deletions

View file

@ -53,6 +53,11 @@ module type S = sig
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** fold left on array, with index *)
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
(** fold left on array until a stop condition via [('a, `Stop)] is
indicated by the accumulator
@since NEXT_RELEASE *)
val iter : ('a -> unit) -> 'a t -> unit
val iteri : (int -> 'a -> unit) -> 'a t -> unit
@ -276,6 +281,20 @@ let fold = Array.fold_left
let foldi f acc a = _foldi f acc a 0 (Array.length a)
let fold_while f acc a =
let rec fold_while_i f acc i =
if i < Array.length a then
let acc, cont = f acc a.(i) in
match cont with
| `Stop -> acc
| `Continue -> fold_while_i f acc (i+1)
else acc
in fold_while_i f acc 0
(*$T
fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 (Array.of_list [true;true;false;true]) = 2
*)
let iter = Array.iter
let iteri = Array.iteri
@ -480,6 +499,16 @@ module Sub = struct
let foldi f acc a = _foldi f acc a.arr a.i a.j
let fold_while f acc a =
let rec fold_while_i f acc i =
if i < Array.length a.arr && i < a.j then
let acc, cont = f acc a.arr.(i) in
match cont with
| `Stop -> acc
| `Continue -> fold_while_i f acc (i+1)
else acc
in fold_while_i f acc a.i
let get a i =
let j = a.i + i in
if i<0 || j>=a.j then invalid_arg "Array.Sub.get";

View file

@ -50,10 +50,15 @@ module type S = sig
val length : _ t -> int
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** fold left on array, with index *)
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
(** Fold left on array, with index *)
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
(** Fold left on array until a stop condition via [('a, `Stop)] is
indicated by the accumulator
@since NEXT_RELEASE *)
val iter : ('a -> unit) -> 'a t -> unit

View file

@ -116,6 +116,17 @@ let fold_right f l acc =
l = fold_right (fun x y->x::y) l [])
*)
let rec fold_while f acc = function
| [] -> acc
| e::l -> let acc, cont = f acc e in
match cont with
| `Stop -> acc
| `Continue -> fold_while f acc l
(*$T
fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 [true;true;false;true] = 2
*)
let init len f =
let rec init_rec acc i f =
if i=0 then f i :: acc

View file

@ -48,6 +48,11 @@ val filter : ('a -> bool) -> 'a t -> 'a t
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 NEXT_RELEASE *)
val init : int -> (int -> 'a) -> 'a t
(** Same as [Array.init]
@since 0.6 *)