diff --git a/sequence.ml b/sequence.ml index 4906b5d..6c3f2f0 100644 --- a/sequence.ml +++ b/sequence.ml @@ -34,6 +34,16 @@ type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit (** Build a sequence from a iter function *) let from_iter f = f +(** Call the function repeatedly until it returns None. This + sequence is transient, use {!persistent} if needed! *) +let from_fun f = + fun k -> + let rec next () = + match f () with + | None -> () + | Some x -> (k x; next ()) + in next () + let empty = fun k -> () let singleton x = fun k -> k x @@ -117,10 +127,11 @@ let flatMap f seq = from_iter (fun k -> seq (fun x -> (f x) k)) -(** Insert the second element between every element of the sequence *) -let intersperse seq elem = - from_iter - (fun k -> seq (fun x -> k x; k elem)) +(** Insert the given element between every element of the sequence *) +let intersperse elem seq = + fun k -> + let first = ref true in + seq (fun x -> (if !first then first := false else k elem); k x) (** Mutable unrolled list to serve as intermediate storage *) module MList = struct diff --git a/sequence.mli b/sequence.mli index 088e5eb..1ac41ba 100644 --- a/sequence.mli +++ b/sequence.mli @@ -50,6 +50,10 @@ type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit val from_iter : (('a -> unit) -> unit) -> 'a t (** Build a sequence from a iter function *) +val from_fun : (unit -> 'a option) -> 'a t + (** Call the function repeatedly until it returns None. This + sequence is transient, use {!persistent} if needed! *) + val empty : 'a t (** Empty sequence *) @@ -66,8 +70,7 @@ val forever : (unit -> 'b) -> 'b t (** Sequence that calls the given function to produce elements *) val cycle : 'a t -> 'a t - (** Cycle forever through the given sequence. Assume the - given sequence can be traversed any amount of times (not transient). *) + (** Cycle forever through the given sequence. *) (** {2 Consume a sequence} *) @@ -119,7 +122,7 @@ val flatMap : ('a -> 'b t) -> 'a t -> 'b t (** Monadic bind. It applies the function to every element of the initial sequence, and calls [concat]. *) -val intersperse : 'a t -> 'a -> 'a t +val intersperse : 'a -> 'a t -> 'a t (** Insert the second element between every element of the sequence *) val persistent : 'a t -> 'a t diff --git a/tests/test_sequence.ml b/tests/test_sequence.ml index e0b3c5c..0d7a928 100644 --- a/tests/test_sequence.ml +++ b/tests/test_sequence.ml @@ -71,7 +71,7 @@ let test_flatMap () = let test_intersperse () = 1 -- 100 - |> (fun seq -> S.intersperse seq 0) + |> (fun seq -> S.intersperse 0 seq) |> S.take 10 |> S.to_list |> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]