From 099b0bbb8d3d945f290b2b3cca4a8d259d424f0f Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 18 Feb 2013 17:20:15 +0100 Subject: [PATCH] some combinators (inspired by Data.List in Haskell): intersperse, product, unfoldr, max and min --- sequence.ml | 31 +++++++++++++++++++++++++++++++ sequence.mli | 19 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/sequence.ml b/sequence.ml index b1a562c..c71c71c 100644 --- a/sequence.ml +++ b/sequence.ml @@ -110,6 +110,37 @@ 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)) + +(** Cartesian product of the sequences. *) +let product outer inner = + from_iter + (fun k -> + outer (fun x -> + inner (fun y -> k (x,y)))) + +(** [unfoldr f b] will apply [f] to [b]. If it + yields [Some (x,b')] then [x] is returned + and unfoldr recurses with [b']. *) +let unfoldr f b = + let rec unfold k b = match f b with + | None -> () + | Some (x, b') -> k x; unfold k b' + in + from_iter (fun k -> unfold k b) + +(** Max element of the sequence, using the given comparison + function. A default element has to be provided. *) +let max ?(lt=fun x y -> x < y) seq m = + fold (fun m x -> if lt m x then x else m) m seq + +(** Min element of the sequence, using the given comparison function *) +let min ?(lt=fun x y -> x < y) seq m = + fold (fun m x -> if lt x m then x else m) m seq + exception ExitSequence (** Take at most [n] elements from the sequence *) diff --git a/sequence.mli b/sequence.mli index 3c377d0..df96b51 100644 --- a/sequence.mli +++ b/sequence.mli @@ -99,6 +99,25 @@ 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 + (** Insert the second element between every element of the sequence *) + +val product : 'a t -> 'b t -> ('a * 'b) t + (** Cartesian product of the sequences. The first one is outer + and therefore must be traversable several times. *) + +val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t + (** [unfoldr f b] will apply [f] to [b]. If it + yields [Some (x,b')] then [x] is returned + and unfoldr recurses with [b']. *) + +val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a -> 'a + (** Max element of the sequence, using the given comparison + function. A default element has to be provided. *) + +val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a -> 'a + (** Min element of the sequence, using the given comparison function *) + val take : int -> 'a t -> 'a t (** Take at most [n] elements from the sequence *)