mirror of
https://github.com/c-cube/iter.git
synced 2025-12-05 19:00:31 -05:00
Add Iter.map_while
This commit is contained in:
parent
67c46b6ce4
commit
4bf00eabad
5 changed files with 39 additions and 1 deletions
|
|
@ -17,6 +17,7 @@ depends: [
|
||||||
"ounit2" {with-test}
|
"ounit2" {with-test}
|
||||||
"mdx" {with-test & >= "1.3" }
|
"mdx" {with-test & >= "1.3" }
|
||||||
"odoc" {with-doc}
|
"odoc" {with-doc}
|
||||||
|
"containers" {with-test}
|
||||||
]
|
]
|
||||||
tags: [ "iter" "iterator" "iter" "fold" ]
|
tags: [ "iter" "iterator" "iter" "fold" ]
|
||||||
homepage: "https://github.com/c-cube/iter/"
|
homepage: "https://github.com/c-cube/iter/"
|
||||||
|
|
|
||||||
10
src/Iter.ml
10
src/Iter.ml
|
|
@ -658,6 +658,16 @@ let take_while p seq k =
|
||||||
|
|
||||||
exception ExitFoldWhile
|
exception ExitFoldWhile
|
||||||
|
|
||||||
|
let map_while f seq k =
|
||||||
|
let exception ExitMapWhile in
|
||||||
|
let consume x =
|
||||||
|
match f x with
|
||||||
|
| `Yield y -> k y
|
||||||
|
| `Return y -> k y; raise_notrace ExitMapWhile
|
||||||
|
| `Stop -> raise_notrace ExitMapWhile
|
||||||
|
in
|
||||||
|
try seq consume with ExitMapWhile -> ()
|
||||||
|
|
||||||
let fold_while f s seq =
|
let fold_while f s seq =
|
||||||
let state = ref s in
|
let state = ref s in
|
||||||
let consume x =
|
let consume x =
|
||||||
|
|
|
||||||
11
src/Iter.mli
11
src/Iter.mli
|
|
@ -487,6 +487,17 @@ val take_while : ('a -> bool) -> 'a t -> 'a t
|
||||||
Will work on an infinite iterator [s] if the predicate is false for at
|
Will work on an infinite iterator [s] if the predicate is false for at
|
||||||
least one element of [s]. *)
|
least one element of [s]. *)
|
||||||
|
|
||||||
|
val map_while : ('a -> [ `Yield of 'b | `Return of 'b | `Stop ]) -> 'a t -> 'b t
|
||||||
|
(** Maps over elements of the iterator, stopping early if the mapped function
|
||||||
|
returns [`Stop] or [`Return x]. At each iteration:
|
||||||
|
{ul
|
||||||
|
{- If [f] returns [`Yield y], [y] is added to the sequence and the
|
||||||
|
iteration continues.}
|
||||||
|
{- If [f] returns [`Stop], nothing is added to the sequence and the
|
||||||
|
iteration stops.}
|
||||||
|
{- If [f] returns [`Return y], [y] is added to the sequence and the
|
||||||
|
iteration stops.}} *)
|
||||||
|
|
||||||
val fold_while : ('a -> 'b -> 'a * [ `Stop | `Continue ]) -> 'a -> 'b t -> 'a
|
val fold_while : ('a -> 'b -> 'a * [ `Stop | `Continue ]) -> 'a -> 'b t -> 'a
|
||||||
(** Folds over elements of the iterator, stopping early if the accumulator
|
(** Folds over elements of the iterator, stopping early if the accumulator
|
||||||
returns [('a, `Stop)]
|
returns [('a, `Stop)]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
(tests
|
(tests
|
||||||
(names t_iter)
|
(names t_iter)
|
||||||
(libraries iter qcheck-core qcheck-core.runner ounit2))
|
(libraries iter qcheck-core qcheck-core.runner ounit2 containers))
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,22 @@ let () =
|
||||||
OUnit.assert_equal 2 n;
|
OUnit.assert_equal 2 n;
|
||||||
()
|
()
|
||||||
|
|
||||||
|
let () =
|
||||||
|
OUnit.assert_equal
|
||||||
|
~cmp:(CCList.equal Int.equal)
|
||||||
|
(1 -- 10
|
||||||
|
|> map_while (fun x -> if x = 7 then `Return (x + 1) else `Yield (x - 1))
|
||||||
|
|> to_list)
|
||||||
|
[0; 1; 2; 3; 4; 5; 8]
|
||||||
|
|
||||||
|
let () =
|
||||||
|
OUnit.assert_equal
|
||||||
|
~cmp:(List.equal Int.equal)
|
||||||
|
(1 -- 10
|
||||||
|
|> map_while (fun x -> if x = 7 then `Stop else `Yield (x - 1))
|
||||||
|
|> to_list)
|
||||||
|
[0; 1; 2; 3; 4; 5]
|
||||||
|
|
||||||
let () = 1 -- 5 |> drop 2 |> to_list |> OUnit.assert_equal [ 3; 4; 5 ]
|
let () = 1 -- 5 |> drop 2 |> to_list |> OUnit.assert_equal [ 3; 4; 5 ]
|
||||||
let () = 1 -- 5 |> rev |> to_list |> OUnit.assert_equal [ 5; 4; 3; 2; 1 ]
|
let () = 1 -- 5 |> rev |> to_list |> OUnit.assert_equal [ 5; 4; 3; 2; 1 ]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue