Enum.Infix with some basic infix operators;

fixed bugs in Enum
This commit is contained in:
Simon Cruanes 2013-03-18 23:59:30 +01:00
parent a378af8a8e
commit 81e30d76bf
2 changed files with 47 additions and 6 deletions

46
enum.ml
View file

@ -57,8 +57,8 @@ let is_empty enum =
let fold f acc enum = let fold f acc enum =
let rec fold acc gen = let rec fold acc gen =
let acc', stop = let acc', stop =
try f acc (gen ()), true try f acc (gen ()), false
with EOG -> acc, false in with EOG -> acc, true in
if stop then acc' else fold acc' gen if stop then acc' else fold acc' gen
in in
fold acc (enum ()) fold acc (enum ())
@ -66,8 +66,8 @@ let fold f acc enum =
let iter f enum = let iter f enum =
let rec iter gen = let rec iter gen =
let stop = let stop =
try f (gen ()); true try f (gen ()); false
with EOG -> false in with EOG -> true in
if stop then () else iter gen if stop then () else iter gen
in in
iter (enum ()) iter (enum ())
@ -109,12 +109,27 @@ let flatten enum =
with EOG -> with EOG ->
(* jump to next sub-enum *) (* jump to next sub-enum *)
let stop = let stop =
try gen := !next_gen (); false try gen := (next_gen () ()); false
with EOG -> true in with EOG -> true in
if stop then raise EOG else next () if stop then raise EOG else next ()
in next in next
let flatMap f enum = flatten (map f enum) let flatMap f enum =
fun () ->
let next_elem = enum () in
let gen = ref (fun () -> raise EOG) in
(* get next element *)
let rec next () =
try !gen ()
with EOG ->
(* enumerate f (next element) *)
let stop =
try
let x = next_elem () in
gen := (f x) (); false
with EOG -> true in
if stop then raise EOG else next ()
in next
let of_list l = let of_list l =
fun () -> fun () ->
@ -138,3 +153,22 @@ let to_rev_list enum =
in if stop then acc' else fold acc' gen in if stop then acc' else fold acc' gen
in in
fold [] (enum ()) fold [] (enum ())
let int_range i j =
fun () ->
let r = ref i in
fun () ->
if !r > j then raise EOG
else begin
let x = !r in
incr r;
x
end
module Infix = struct
let (@@) = append
let (>>=) e f = flatMap f e
let (--) = int_range
end

View file

@ -85,3 +85,10 @@ val to_list : 'a t -> 'a list
val to_rev_list : 'a t -> 'a list val to_rev_list : 'a t -> 'a list
(** Tail call conversion to list, in reverse order *) (** Tail call conversion to list, in reverse order *)
val int_range : int -> int -> int t
module Infix : sig
val (@@) : 'a t -> 'a t -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
val (--) : int -> int -> int t
end