Implement missing functions from Lwt_klist

This commit is contained in:
Simon Cruanes 2015-02-20 18:19:30 +01:00
parent d338ce279c
commit c16783f513
2 changed files with 86 additions and 19 deletions

View file

@ -37,11 +37,6 @@ let empty = Lwt.return `Nil
let cons x l = Lwt.return (`Cons (x, l)) let cons x l = Lwt.return (`Cons (x, l))
let rec create f : 'a t = let rec create f : 'a t =
let fut, wake = Lwt.wait () in
f () >|= function
| None -> `Nil
| Some x -> `Cons (x, create f)
and create_rec f () =
f () >|= function f () >|= function
| None -> `Nil | None -> `Nil
| Some x -> `Cons (x, create f) | Some x -> `Cons (x, create f)
@ -115,13 +110,66 @@ let rec fold_s f acc l =
| `Nil -> Lwt.return acc | `Nil -> Lwt.return acc
| `Cons (x, tl) -> f acc x >>= fun acc -> fold_s f acc tl | `Cons (x, tl) -> f acc x >>= fun acc -> fold_s f acc tl
let take n l = assert false let rec take n l = match n with
let take_while f l = assert false | 0 -> empty
let take_while_s f l = assert false | _ ->
let drop n l = assert false l >>= function
let drop_while f l = assert false | `Nil -> empty
let drop_while_s f l = assert false | `Cons (x, tl) -> Lwt.return (`Cons (x, take (n-1) tl))
let merge a b = assert false
let rec take_while f l =
l >>= function
| `Cons (x, tl) when f x -> Lwt.return (`Cons (x, take_while f tl))
| `Nil
| `Cons _ -> empty
let rec take_while_s f l =
l >>= function
| `Nil -> empty
| `Cons (x, tl) ->
f x >>= function
| true -> Lwt.return (`Cons (x, take_while_s f tl))
| false -> empty
let rec drop n l = match n with
| 0 -> l
| _ ->
l >>= function
| `Nil -> empty
| `Cons (_, tl) -> drop (n-1) tl
let rec drop_while f l =
l >>= function
| `Nil -> empty
| `Cons (x, _) when f x -> l
| `Cons (_, tl) -> drop_while f tl
let rec drop_while_s f l =
l >>= function
| `Nil -> empty
| `Cons (x, tl) ->
f x >>= function
| false -> drop_while_s f tl
| true -> l
let merge a b =
let add_left = Lwt.map (fun y -> `Left y) in
let add_right = Lwt.map (fun y -> `Right y) in
let remove_side l =
l >|= function
| `Left x -> x
| `Right x -> x
in
let rec merge' l r =
Lwt.choose [l; r] >>= function
| `Left `Nil -> remove_side r
| `Left (`Cons (x, l')) ->
Lwt.return (`Cons (x, merge' (add_left l') r))
| `Right `Nil -> remove_side l
| `Right (`Cons (x, r')) ->
Lwt.return (`Cons (x, merge' l (add_right r')))
in
merge' (add_left a) (add_right b)
(** {2 Conversions} *) (** {2 Conversions} *)
@ -132,7 +180,7 @@ let rec of_list l = match l with
| x :: tl -> Lwt.return (`Cons (x, of_list tl)) | x :: tl -> Lwt.return (`Cons (x, of_list tl))
let rec of_array_rec a i = let rec of_array_rec a i =
if i = Array.length a if i = Array.length a
then empty then empty
else Lwt.return (`Cons (a.(i), of_array_rec a (i+1))) else Lwt.return (`Cons (a.(i), of_array_rec a (i+1)))
@ -147,7 +195,20 @@ let rec of_gen_s g = match g() with
| Some x -> | Some x ->
x >|= fun x -> `Cons (x, of_gen_s g) x >|= fun x -> `Cons (x, of_gen_s g)
let of_string s = assert false let rec of_string_rec s i =
let to_string l = assert false if i = String.length s
let to_list l = assert false then empty
let to_rev_list l = assert false else Lwt.return (`Cons (String.get s i, of_string_rec s (i+1)))
let of_string s : char t = of_string_rec s 0
let to_string l =
let buf = Buffer.create 128 in
iter (fun c -> Buffer.add_char buf c) l >>= fun () ->
Lwt.return (Buffer.contents buf)
let to_rev_list l =
fold (fun acc x -> x :: acc) [] l
let to_list l = to_rev_list l >|= List.rev

View file

@ -24,7 +24,13 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*) *)
(** {1 Functional streams for Lwt} *) (** {1 Functional streams for Lwt}
Functional streams, that is, lazy lists whose nodes are behind a
Lwt.t future. Such as list never mutates, it can be safely traversed
several times, but might eat memory.
@since NEXT_RELEASE *)
type 'a t = [ `Nil | `Cons of 'a * 'a t ] Lwt.t type 'a t = [ `Nil | `Cons of 'a * 'a t ] Lwt.t
type 'a stream = 'a t type 'a stream = 'a t
@ -90,7 +96,7 @@ val of_gen : 'a gen -> 'a t
val of_gen_s : 'a Lwt.t gen -> 'a t val of_gen_s : 'a Lwt.t gen -> 'a t
val of_string : string -> 'a t val of_string : string -> char t
val to_list : 'a t -> 'a list Lwt.t val to_list : 'a t -> 'a list Lwt.t