From 691f4e5068e0b79aa7fd3d326cc3b9eaed5395f9 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 5 Aug 2014 00:32:45 +0200 Subject: [PATCH] more CCIO.Seq combinators --- core/CCIO.ml | 38 ++++++++++++++++++++++++++++++++++++++ core/CCIO.mli | 13 ++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/core/CCIO.ml b/core/CCIO.ml index f91e33cb..cb688075 100644 --- a/core/CCIO.ml +++ b/core/CCIO.ml @@ -261,6 +261,12 @@ module Seq = struct | None -> filter_map f g() | Some y -> _yield y + let rec filter f g () = + g() >>= function + | Stop -> _stop() + | Yield x -> + if f x then _yield x else filter f g() + let rec flat_map f g () = g() >>= function | Stop -> _stop () @@ -287,6 +293,38 @@ module Seq = struct in _next + let take n seq = + general_iter + (fun n x -> if n<=0 + then return `Stop + else return (`Continue (n-1, Some x)) + ) n seq + + let drop n seq = + general_iter + (fun n x -> if n<=0 + then return (`Continue (n, Some x)) + else return (`Continue (n-1, None)) + ) n seq + + let take_while p seq = + general_iter + (fun () x -> + p x >|= function + | true -> `Continue ((), Some x) + | false -> `Stop + ) () seq + + let drop_while p seq = + general_iter + (fun dropping x -> + if dropping + then p x >|= function + | true -> `Continue (true, None) + | false -> `Continue (false, Some x) + else return (`Continue (false, Some x)) + ) true seq + (* apply all actions from [l] to [x] *) let rec _apply_all_to x l = match l with | [] -> return () diff --git a/core/CCIO.mli b/core/CCIO.mli index 155c5c2a..1d097617 100644 --- a/core/CCIO.mli +++ b/core/CCIO.mli @@ -195,9 +195,19 @@ module Seq : sig val filter_map : ('a -> 'b option) -> 'a t -> 'b t + val filter : ('a -> bool) -> 'a t -> 'a t + val flat_map : ('a -> 'b t io) -> 'a t -> 'b t (** Map each value to a sub sequence of values *) + val take : int -> 'a t -> 'a t + + val drop : int -> 'a t -> 'a t + + val take_while : ('a -> bool io) -> 'a t -> 'a t + + val drop_while : ('a -> bool io) -> 'a t -> 'a t + val general_iter : ('b -> 'a -> [`Stop | `Continue of ('b * 'c option)] io) -> 'b -> 'a t -> 'c t (** [general_iter f acc seq] performs a [filter_map] over [seq], @@ -245,7 +255,8 @@ module Seq : sig (** Lines of an input channel *) val words : string t -> string t - (** Split strings into words at " " boundaries *) + (** Split strings into words at " " boundaries. + {b NOT IMPLEMENTED} *) val output : ?sep:string -> out_channel -> string t -> unit io (** [output oc seq] outputs every value of [seq] into [oc], separated