diff --git a/sequence.ml b/sequence.ml index cc14f74..65edcbe 100644 --- a/sequence.ml +++ b/sequence.ml @@ -321,6 +321,17 @@ let min ?(lt=fun x y -> x < y) seq = exception ExitSequence +let head seq = + let r = ref None in + try + seq (fun x -> r := Some x; raise ExitSequence); None + with ExitSequence -> !r + +let head_exn seq = + match head seq with + | None -> invalid_arg "Sequence.head_exn" + | Some x -> x + let take n seq k = let count = ref 0 in try @@ -425,6 +436,12 @@ let to_list seq = List.rev (fold (fun y x -> x::y) [] seq) let to_rev_list seq = fold (fun y x -> x :: y) [] seq +let to_opt = head + +let of_opt o k = match o with + | None -> () + | Some x -> k x + let of_list l k = List.iter k l let to_array seq = diff --git a/sequence.mli b/sequence.mli index 6a84dfb..5d2817e 100644 --- a/sequence.mli +++ b/sequence.mli @@ -254,6 +254,15 @@ val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option (** Min element of the sequence, using the given comparison function. see {!max} for more details. *) +val head : 'a t -> 'a option + (** First element, if any, otherwise [None] + @since NEXT_RELEASE *) + +val head_exn : 'a t -> 'a + (** First element, if any, fails + @raise Invalid_argument if the sequence is empty + @since NEXT_RELEASE *) + val take : int -> 'a t -> 'a t (** Take at most [n] elements from the sequence. Works on infinite sequences. *) @@ -310,6 +319,10 @@ val to_rev_list : 'a t -> 'a list val of_list : 'a list -> 'a t +val to_opt : 'a t -> 'a option + (** Alias to {!head} + @since NEXT_RELEASE *) + val to_array : 'a t -> 'a array (** Convert to an array. Currently not very efficient because an intermediate list is used. *) @@ -325,6 +338,10 @@ val array_slice : 'a array -> int -> int -> 'a t (** [array_slice a i j] Sequence of elements whose indexes range from [i] to [j] *) +val of_opt : 'a option -> 'a t + (** Iterate on 0 or 1 values. + @since NEXT_RELEASE *) + val of_stream : 'a Stream.t -> 'a t (** Sequence of elements of a stream (usable only once) *)