add CCList.partition_map

This commit is contained in:
Simon Cruanes 2015-05-05 23:47:22 +02:00
parent 61c5e5ec3f
commit d2a02793e2
2 changed files with 31 additions and 0 deletions

View file

@ -206,6 +206,29 @@ let diagonal l =
in in
gen [] l gen [] l
let partition_map f l =
let rec iter f l1 l2 l = match l with
| [] -> List.rev l1, List.rev l2
| x :: tl ->
match f x with
| `Left y -> iter f (y :: l1) l2 tl
| `Right y -> iter f l1 (y :: l2) tl
| `Drop -> iter f l1 l2 tl
in
iter f [] [] l
(*$R
let l1, l2 =
partition_map (function
| n when n = 0 -> `Drop
| n when n mod 2 = 0 -> `Left n
| n -> `Right n
) [0;1;2;3;4]
in
assert_equal [2;4] l1;
assert_equal [1;3] l2
*)
let return x = [x] let return x = [x]
let (>>=) l f = flat_map f l let (>>=) l f = flat_map f l

View file

@ -77,6 +77,14 @@ val diagonal : 'a t -> ('a * 'a) t
(** All pairs of distinct positions of the list. [list_diagonal l] will (** All pairs of distinct positions of the list. [list_diagonal l] will
return the list of [List.nth i l, List.nth j l] if [i < j]. *) return the list of [List.nth i l, List.nth j l] if [i < j]. *)
val partition_map : ('a -> [<`Left of 'b | `Right of 'c | `Drop]) ->
'a list -> 'b list * 'c list
(** [partition_map f l] maps [f] on [l] and gather results in lists:
- if [f x = `Left y], adds [y] to the first list
- if [f x = `Right z], adds [z] to the second list
- if [f x = `Drop], ignores [x]
@since NEXT_RELEASE *)
val pure : 'a -> 'a t val pure : 'a -> 'a t
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t val (<*>) : ('a -> 'b) t -> 'a t -> 'b t