append, flatMap and flatten in Enum

This commit is contained in:
Simon Cruanes 2013-03-18 23:42:29 +01:00
parent 5d289098b0
commit a378af8a8e
2 changed files with 41 additions and 0 deletions

32
enum.ml
View file

@ -83,6 +83,38 @@ let map f enum =
fun () ->
try f (gen ())
with EOG -> raise EOG
let append e1 e2 =
fun () ->
let gen = ref (e1 ()) in
let first = ref true in
(* get next element *)
let rec next () =
try !gen ()
with EOG ->
if !first then begin
first := false;
gen := e2 (); (* switch to the second generator *)
next ()
end else raise EOG (* done *)
in next
let flatten enum =
fun () ->
let next_gen = enum () in
let gen = ref (fun () -> raise EOG) in
(* get next element *)
let rec next () =
try !gen ()
with EOG ->
(* jump to next sub-enum *)
let stop =
try gen := !next_gen (); false
with EOG -> true in
if stop then raise EOG else next ()
in next
let flatMap f enum = flatten (map f enum)
let of_list l =
fun () ->

View file

@ -67,6 +67,15 @@ val length : _ t -> int
val map : ('a -> 'b) -> 'a t -> 'b t
(** Lazy map *)
val append : 'a t -> 'a t -> 'a t
(** Append the two enums *)
val flatten : 'a t t -> 'a t
(** Flatten the enum of enum *)
val flatMap : ('a -> 'b t) -> 'a t -> 'b t
(** Monadic bind *)
val of_list : 'a list -> 'a t
(** Enumerate the list *)