CCKList: group,uniq,sort,sort_uniq,repeat and cycle

This commit is contained in:
Simon Cruanes 2014-07-18 02:51:23 +02:00
parent a27e252cf1
commit 556d10a0d4
2 changed files with 68 additions and 0 deletions

View file

@ -43,6 +43,15 @@ let empty = nil
let singleton x () = `Cons (x, nil)
let rec _forever x () = `Cons (x, _forever x)
let rec _repeat n x () =
if n<=0 then `Nil else `Cons (x, _repeat (n-1) x)
let repeat ?n x = match n with
| None -> _forever x
| Some n -> _repeat n x
let is_empty l = match l () with
| `Nil -> true
| `Cons _ -> false
@ -130,6 +139,8 @@ let rec append l1 l2 () = match l1 () with
| `Nil -> l2 ()
| `Cons (x, l1') -> `Cons (x, append l1' l2)
let rec cycle l () = append l (cycle l) ()
let rec flat_map f l () = match l () with
| `Nil -> `Nil
| `Cons (x, l') ->
@ -167,6 +178,22 @@ let product_with f l1 l2 =
let product l1 l2 =
product_with (fun x y -> x,y) l1 l2
let rec group eq l () = match l() with
| `Nil -> `Nil
| `Cons (x, l') ->
`Cons (cons x (take_while (eq x) l'), group eq (drop_while (eq x) l'))
let rec _uniq eq prev l () = match prev, l() with
| _, `Nil -> `Nil
| None, `Cons (x, l') ->
`Cons (x, _uniq eq (Some x) l')
| Some y, `Cons (x, l') ->
if eq x y
then _uniq eq prev l' ()
else `Cons (x, _uniq eq (Some x) l')
let uniq eq l = _uniq eq None l
let rec filter_map f l () = match l() with
| `Nil -> `Nil
| `Cons (x, l') ->
@ -274,6 +301,15 @@ let to_gen l =
l := l';
Some x
let sort ?(cmp=Pervasives.compare) l =
let l = to_list l in
of_list (List.sort cmp l)
let sort_uniq ?(cmp=Pervasives.compare) l =
let l = to_list l in
uniq (fun x y -> cmp x y = 0) (of_list (List.sort cmp l))
(** {2 Monadic Operations} *)
module type MONAD = sig
type 'a t

View file

@ -47,6 +47,16 @@ val cons : 'a -> 'a t -> 'a t
val singleton : 'a -> 'a t
val repeat : ?n:int -> 'a -> 'a t
(** [repeat ~n x] repeats [x] [n] times then stops. If [n] is omitted,
then [x] is repeated forever.
@since NEXT_RELEASE *)
val cycle : 'a t -> 'a t
(** Cycle through the iterator infinitely. The iterator shouldn't be empty.
@since NEXT_RELEASE *)
val is_empty : 'a t -> bool
val equal : 'a equal -> 'a t equal
@ -87,6 +97,18 @@ val product : 'a t -> 'b t -> ('a * 'b) t
(** Specialization of {!product_with} producing tuples
@since NEXT_RELEASE *)
val group : 'a equal -> 'a t -> 'a t t
(** [group eq l] groups together consecutive elements that satisfy [eq]. Lazy.
For instance [group (=) [1;1;1;2;2;3;3;1]] yields
[[1;1;1]; [2;2]; [3;3]; [1]]
@since NEXT_RELEASE *)
val uniq : 'a equal -> 'a t -> 'a t
(** [uniq eq l] returns [l] but removes consecutive duplicates. Lazy.
In other words, if several values that are equal follow one another,
only the first of them is kept.
@since NEXT_RELEASE *)
val flat_map : ('a -> 'b t) -> 'a t -> 'b t
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
@ -115,6 +137,16 @@ val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
val merge : 'a ord -> 'a t -> 'a t -> 'a t
(** Merge two sorted iterators into a sorted iterator *)
val sort : ?cmp:'a ord -> 'a t -> 'a t
(** Eager sort. Requires the iterator to be finite. O(n ln(n)) time
and space.
@since NEXT_RELEASE *)
val sort_uniq : ?cmp:'a ord -> 'a t -> 'a t
(** Eager sort that removes duplicate values. Requires the iterator to be
finite. O(n ln(n)) time and space.
@since NEXT_RELEASE *)
(** {2 Implementations}
@since NEXT_RELEASE *)