add labels to CCList

This commit is contained in:
Simon Cruanes 2016-11-11 00:52:44 +01:00
parent b1837e7d05
commit a8babbd941
4 changed files with 121 additions and 119 deletions

View file

@ -18,7 +18,7 @@ let is_empty = function
(* max depth for direct recursion *) (* max depth for direct recursion *)
let direct_depth_default_ = 1000 let direct_depth_default_ = 1000
let map f l = let map ~f l =
let rec direct f i l = match l with let rec direct f i l = match l with
| [] -> [] | [] -> []
| [x] -> [f x] | [x] -> [f x]
@ -40,7 +40,7 @@ let map f l =
List.rev (List.rev_map f l) = map f l) List.rev (List.rev_map f l) = map f l)
*) *)
let (>|=) l f = map f l let (>|=) l f = map ~f:f l
let direct_depth_append_ = 10_000 let direct_depth_append_ = 10_000
@ -78,7 +78,7 @@ let cons_maybe o l = match o with
let direct_depth_filter_ = 10_000 let direct_depth_filter_ = 10_000
let filter p l = let filter ~f l =
let rec direct i p l = match l with let rec direct i p l = match l with
| [] -> [] | [] -> []
| _ when i=0 -> safe p l [] | _ when i=0 -> safe p l []
@ -89,7 +89,7 @@ let filter p l =
| x::l' when not (p x) -> safe p l' acc | x::l' when not (p x) -> safe p l' acc
| x::l' -> safe p l' (x::acc) | x::l' -> safe p l' (x::acc)
in in
direct direct_depth_filter_ p l direct direct_depth_filter_ f l
(*$= & ~printer:CCInt.to_string (*$= & ~printer:CCInt.to_string
500 (filter (fun x->x mod 2 = 0) (1 -- 1000) |> List.length) 500 (filter (fun x->x mod 2 = 0) (1 -- 1000) |> List.length)
@ -122,37 +122,38 @@ let fold_right f l acc =
l = fold_right (fun x y->x::y) l []) l = fold_right (fun x y->x::y) l [])
*) *)
let rec fold_while f acc = function let rec fold_while ~f ~init:acc = function
| [] -> acc | [] -> acc
| e::l -> let acc, cont = f acc e in | e::l -> let acc, cont = f acc e in
match cont with match cont with
| `Stop -> acc | `Stop -> acc
| `Continue -> fold_while f acc l | `Continue -> fold_while ~f ~init:acc l
(*$T (*$T
fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 [true;true;false;true] = 2 fold_while ~f:(fun acc b -> if b then acc+1, `Continue else acc, `Stop) \
~init:0 [true;true;false;true] = 2
*) *)
let fold_map f acc l = let fold_map ~f ~init l =
let rec aux f acc map_acc l = match l with let rec aux f acc map_acc l = match l with
| [] -> acc, List.rev map_acc | [] -> acc, List.rev map_acc
| x :: l' -> | x :: l' ->
let acc, y = f acc x in let acc, y = f acc x in
aux f acc (y :: map_acc) l' aux f acc (y :: map_acc) l'
in in
aux f acc [] l aux f init [] l
(*$= (*$=
(6, ["1"; "2"; "3"]) \ (6, ["1"; "2"; "3"]) \
(fold_map (fun acc x->acc+x, string_of_int x) 0 [1;2;3]) (fold_map ~f:(fun acc x->acc+x, string_of_int x) ~init:0 [1;2;3])
*) *)
(*$Q (*$Q
Q.(list int) (fun l -> \ Q.(list int) (fun l -> \
fold_map (fun acc x -> x::acc, x) [] l = (List.rev l, l)) fold_map ~f:(fun acc x -> x::acc, x) ~init:[] l = (List.rev l, l))
*) *)
let fold_map2 f acc l1 l2 = let fold_map2 ~f ~init l1 l2 =
let rec aux f acc map_acc l1 l2 = match l1, l2 with let rec aux f acc map_acc l1 l2 = match l1, l2 with
| [], [] -> acc, List.rev map_acc | [], [] -> acc, List.rev map_acc
| [], _ | [], _
@ -161,56 +162,56 @@ let fold_map2 f acc l1 l2 =
let acc, y = f acc x1 x2 in let acc, y = f acc x1 x2 in
aux f acc (y :: map_acc) l1' l2' aux f acc (y :: map_acc) l1' l2'
in in
aux f acc [] l1 l2 aux f init [] l1 l2
(*$= (*$=
(310, ["1 10"; "2 0"; "3 100"]) \ (310, ["1 10"; "2 0"; "3 100"]) \
(fold_map2 (fun acc x y->acc+x*y, string_of_int x ^ " " ^ string_of_int y) \ (fold_map2 ~f:(fun acc x y->acc+x*y, string_of_int x ^ " " ^ string_of_int y) \
0 [1;2;3] [10;0;100]) ~init:0 [1;2;3] [10;0;100])
*) *)
(*$T (*$T
(try ignore (fold_map2 (fun _ _ _ -> assert false) 42 [] [1]); false \ (try ignore (fold_map2 ~f:(fun _ _ _ -> assert false) ~init:42 [] [1]); false \
with Invalid_argument _ -> true) with Invalid_argument _ -> true)
*) *)
let fold_filter_map f acc l = let fold_filter_map ~f ~init l =
let rec aux f acc map_acc l = match l with let rec aux f acc map_acc l = match l with
| [] -> acc, List.rev map_acc | [] -> acc, List.rev map_acc
| x :: l' -> | x :: l' ->
let acc, y = f acc x in let acc, y = f acc x in
aux f acc (cons_maybe y map_acc) l' aux f acc (cons_maybe y map_acc) l'
in in
aux f acc [] l aux f init [] l
(*$= & ~printer:Q.Print.(pair int (list int)) (*$= & ~printer:Q.Print.(pair int (list int))
(List.fold_left (+) 0 (1--10), [2;4;6;8;10]) \ (List.fold_left (+) 0 (1--10), [2;4;6;8;10]) \
(fold_filter_map (fun acc x -> acc+x, if x mod 2 = 0 then Some x else None) \ (fold_filter_map ~f:(fun acc x -> acc+x, if x mod 2 = 0 then Some x else None) \
0 (1--10)) ~init:0 (1--10))
*) *)
let fold_flat_map f acc l = let fold_flat_map ~f ~init l =
let rec aux f acc map_acc l = match l with let rec aux f acc map_acc l = match l with
| [] -> acc, List.rev map_acc | [] -> acc, List.rev map_acc
| x :: l' -> | x :: l' ->
let acc, y = f acc x in let acc, y = f acc x in
aux f acc (List.rev_append y map_acc) l' aux f acc (List.rev_append y map_acc) l'
in in
aux f acc [] l aux f init [] l
(*$= (*$=
(6, ["1"; "a1"; "2"; "a2"; "3"; "a3"]) \ (6, ["1"; "a1"; "2"; "a2"; "3"; "a3"]) \
(let pf = Printf.sprintf in \ (let pf = Printf.sprintf in \
fold_flat_map (fun acc x->acc+x, [pf "%d" x; pf "a%d" x]) 0 [1;2;3]) fold_flat_map ~f:(fun acc x->acc+x, [pf "%d" x; pf "a%d" x]) ~init:0 [1;2;3])
*) *)
(*$Q (*$Q
Q.(list int) (fun l -> \ Q.(list int) (fun l -> \
fold_flat_map (fun acc x -> x::acc, [x;x+10]) [] l = \ fold_flat_map ~f:(fun acc x -> x::acc, [x;x+10]) ~init:[] l = \
(List.rev l, flat_map (fun x->[x;x+10]) l) ) (List.rev l, flat_map ~f:(fun x->[x;x+10]) l) )
*) *)
let init len f = let init len ~f =
let rec init_rec acc i f = let rec init_rec acc i f =
if i=0 then f i :: acc if i=0 then f i :: acc
else init_rec (f i :: acc) (i-1) f else init_rec (f i :: acc) (i-1) f
@ -220,9 +221,9 @@ let init len f =
else init_rec [] (len-1) f else init_rec [] (len-1) f
(*$T (*$T
init 0 (fun _ -> 0) = [] init 0 ~f:(fun _ -> 0) = []
init 1 (fun x->x) = [0] init 1 ~f:(fun x->x) = [0]
init 1000 (fun x->x) = 0--999 init 1000 ~f:(fun x->x) = 0--999
*) *)
let rec compare f l1 l2 = match l1, l2 with let rec compare f l1 l2 = match l1, l2 with
@ -242,7 +243,7 @@ let rec equal f l1 l2 = match l1, l2 with
equal CCInt.equal (1--1_000_000) (1--1_000_000) equal CCInt.equal (1--1_000_000) (1--1_000_000)
*) *)
let flat_map f l = let flat_map ~f l =
let rec aux f l kont = match l with let rec aux f l kont = match l with
| [] -> kont [] | [] -> kont []
| x::l' -> | x::l' ->
@ -266,19 +267,19 @@ let flatten l = fold_right append l []
(*$T (*$T
flatten [[1]; [2;3;4]; []; []; [5;6]] = 1--6 flatten [[1]; [2;3;4]; []; []; [5;6]] = 1--6
flatten (init 300_001 (fun x->[x])) = 0--300_000 flatten (init 300_001 ~f:(fun x->[x])) = 0--300_000
*) *)
let product f l1 l2 = let product ~f l1 l2 =
flat_map (fun x -> map (fun y -> f x y) l2) l1 flat_map ~f:(fun x -> map ~f:(fun y -> f x y) l2) l1
let fold_product f acc l1 l2 = let fold_product ~f ~init l1 l2 =
List.fold_left List.fold_left
(fun acc x1 -> (fun acc x1 ->
List.fold_left List.fold_left
(fun acc x2 -> f acc x1 x2) (fun acc x2 -> f acc x1 x2)
acc l2 acc l2)
) acc l1 init l1
let diagonal l = let diagonal l =
let rec gen acc l = match l with let rec gen acc l = match l with
@ -296,7 +297,7 @@ let diagonal l =
diagonal [1;2;3] |> List.sort Pervasives.compare = [1, 2; 1, 3; 2, 3] diagonal [1;2;3] |> List.sort Pervasives.compare = [1, 2; 1, 3; 2, 3]
*) *)
let partition_map f l = let partition_map ~f l =
let rec iter f l1 l2 l = match l with let rec iter f l1 l2 l = match l with
| [] -> List.rev l1, List.rev l2 | [] -> List.rev l1, List.rev l2
| x :: tl -> | x :: tl ->
@ -309,11 +310,11 @@ let partition_map f l =
(*$R (*$R
let l1, l2 = let l1, l2 =
partition_map (function partition_map ~f:(function
| n when n = 0 -> `Drop | n when n = 0 -> `Drop
| n when n mod 2 = 0 -> `Left n | n when n mod 2 = 0 -> `Left n
| n -> `Right n | n -> `Right n)
) [0;1;2;3;4] [0;1;2;3;4]
in in
assert_equal [2;4] l1; assert_equal [2;4] l1;
assert_equal [1;3] l2 assert_equal [1;3] l2
@ -321,13 +322,13 @@ let partition_map f l =
let return x = [x] let return x = [x]
let (>>=) l f = flat_map f l let (>>=) l f = flat_map ~f l
let (<$>) = map let (<$>) f x = map ~f x
let pure = return let pure = return
let (<*>) funs l = product (fun f x -> f x) funs l let (<*>) funs l = product ~f:(fun f x -> f x) funs l
let sorted_merge ?(cmp=Pervasives.compare) l1 l2 = let sorted_merge ?(cmp=Pervasives.compare) l1 l2 =
let rec recurse cmp acc l1 l2 = match l1,l2 with let rec recurse cmp acc l1 l2 = match l1,l2 with
@ -530,7 +531,7 @@ let split = take_drop
l1 @ l2 = l ) l1 @ l2 = l )
*) *)
let take_while p l = let take_while ~f l =
let rec direct i p l = match l with let rec direct i p l = match l with
| [] -> [] | [] -> []
| _ when i=0 -> safe p [] l | _ when i=0 -> safe p [] l
@ -541,13 +542,13 @@ let take_while p l =
| x :: l' -> | x :: l' ->
if p x then safe p (x::acc) l' else List.rev acc if p x then safe p (x::acc) l' else List.rev acc
in in
direct direct_depth_default_ p l direct direct_depth_default_ f l
(*$T (*$T
take_while (fun x->x<10) (1 -- 20) = (1--9) take_while ~f:(fun x->x<10) (1 -- 20) = (1--9)
take_while (fun x->x <> 0) [0;1;2;3] = [] take_while ~f:(fun x->x <> 0) [0;1;2;3] = []
take_while (fun _ -> true) [] = [] take_while ~f:(fun _ -> true) [] = []
take_while (fun _ -> true) (1--10) = (1--10) take_while ~f:(fun _ -> true) (1--10) = (1--10)
*) *)
(*$Q (*$Q
@ -556,9 +557,9 @@ let take_while p l =
List.for_all f l1) List.for_all f l1)
*) *)
let rec drop_while p l = match l with let rec drop_while ~f l = match l with
| [] -> [] | [] -> []
| x :: l' -> if p x then drop_while p l' else l | x :: l' -> if f x then drop_while ~f l' else l
(*$Q (*$Q
Q.(pair (fun1 small_int bool) (list small_int)) (fun (f,l) -> \ Q.(pair (fun1 small_int bool) (list small_int)) (fun (f,l) -> \
@ -587,23 +588,23 @@ let rec last_opt = function
None (last_opt []) None (last_opt [])
*) *)
let rec find_pred p l = match l with let rec find_pred ~f l = match l with
| [] -> None | [] -> None
| x :: _ when p x -> Some x | x :: _ when f x -> Some x
| _ :: tl -> find_pred p tl | _ :: tl -> find_pred ~f tl
let find_pred_exn p l = match find_pred p l with let find_pred_exn ~f l = match find_pred ~f l with
| None -> raise Not_found | None -> raise Not_found
| Some x -> x | Some x -> x
(*$T (*$T
find_pred ((=) 4) [1;2;5;4;3;0] = Some 4 find_pred ~f:((=) 4) [1;2;5;4;3;0] = Some 4
find_pred (fun _ -> true) [] = None find_pred ~f:(fun _ -> true) [] = None
find_pred (fun _ -> false) (1 -- 10) = None find_pred ~f:(fun _ -> false) (1 -- 10) = None
find_pred (fun x -> x < 10) (1 -- 9) = Some 1 find_pred ~f:(fun x -> x < 10) (1 -- 9) = Some 1
*) *)
let find_mapi f l = let find_mapi ~f l =
let rec aux f i = function let rec aux f i = function
| [] -> None | [] -> None
| x::l' -> | x::l' ->
@ -612,32 +613,32 @@ let find_mapi f l =
| None -> aux f (i+1) l' | None -> aux f (i+1) l'
in aux f 0 l in aux f 0 l
let find_map f l = find_mapi (fun _ -> f) l let find_map ~f l = find_mapi ~f:(fun _ -> f) l
let find = find_map let find = find_map
let findi = find_mapi let findi = find_mapi
let find_idx p l = find_mapi (fun i x -> if p x then Some (i, x) else None) l let find_idx ~f l = find_mapi ~f:(fun i x -> if f x then Some (i, x) else None) l
(*$T (*$T
find (fun x -> if x=3 then Some "a" else None) [1;2;3;4] = Some "a" find (fun x -> if x=3 then Some "a" else None) [1;2;3;4] = Some "a"
find (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None find (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None
*) *)
let remove ?(eq=(=)) ~x l = let remove ?(eq=(=)) ~key l =
let rec remove' eq x acc l = match l with let rec remove' eq x acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| y :: tail when eq x y -> remove' eq x acc tail | y :: tail when eq x y -> remove' eq x acc tail
| y :: tail -> remove' eq x (y::acc) tail | y :: tail -> remove' eq x (y::acc) tail
in in
remove' eq x [] l remove' eq key [] l
(*$T (*$T
remove ~x:1 [2;1;3;3;2;1] = [2;3;3;2] remove ~key:1 [2;1;3;3;2;1] = [2;3;3;2]
remove ~x:10 [1;2;3] = [1;2;3] remove ~key:10 [1;2;3] = [1;2;3]
*) *)
let filter_map f l = let filter_map ~f l =
let rec recurse acc l = match l with let rec recurse acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| x::l' -> | x::l' ->
@ -718,32 +719,32 @@ let inter ?(eq=(=)) l1 l2 =
inter [1;2;4] [2;3;4;5] = [2;4] inter [1;2;4] [2;3;4;5] = [2;4]
*) *)
let mapi f l = let mapi ~f l =
let r = ref 0 in let r = ref 0 in
map map l
(fun x -> ~f:(fun x ->
let y = f !r x in let y = f !r x in
incr r; y incr r;
) l y)
(*$T (*$T
mapi (fun i x -> i*x) [10;10;10] = [0;10;20] mapi ~f:(fun i x -> i*x) [10;10;10] = [0;10;20]
*) *)
let iteri f l = let iteri ~f l =
let rec aux f i l = match l with let rec aux f i l = match l with
| [] -> () | [] -> ()
| x::l' -> f i x; aux f (i+1) l' | x::l' -> f i x; aux f (i+1) l'
in aux f 0 l in aux f 0 l
let foldi f acc l = let foldi ~f ~init l =
let rec foldi f acc i l = match l with let rec foldi f acc i l = match l with
| [] -> acc | [] -> acc
| x::l' -> | x::l' ->
let acc = f acc i x in let acc = f acc i x in
foldi f acc (i+1) l' foldi f acc (i+1) l'
in in
foldi f acc 0 l foldi f init 0 l
let rec get_at_idx_exn i l = match l with let rec get_at_idx_exn i l = match l with
| [] -> raise Not_found | [] -> raise Not_found
@ -1018,7 +1019,7 @@ end
module Traverse(M : MONAD) = struct module Traverse(M : MONAD) = struct
open M open M
let map_m f l = let map_m ~f l =
let rec aux f acc l = match l with let rec aux f acc l = match l with
| [] -> return (List.rev acc) | [] -> return (List.rev acc)
| x::tail -> | x::tail ->
@ -1026,23 +1027,23 @@ module Traverse(M : MONAD) = struct
aux f (x' :: acc) tail aux f (x' :: acc) tail
in aux f [] l in aux f [] l
let rec map_m_par f l = match l with let rec map_m_par ~f l = match l with
| [] -> M.return [] | [] -> M.return []
| x::tl -> | x::tl ->
let x' = f x in let x' = f x in
let tl' = map_m_par f tl in let tl' = map_m_par ~f tl in
x' >>= fun x' -> x' >>= fun x' ->
tl' >>= fun tl' -> tl' >>= fun tl' ->
M.return (x'::tl') M.return (x'::tl')
let sequence_m l = map_m (fun x->x) l let sequence_m l = map_m l ~f:(fun x->x)
let rec fold_m f acc l = match l with let rec fold_m ~f ~init l = match l with
| [] -> return acc | [] -> return init
| x :: l' -> | x :: l' ->
f acc x f init x
>>= fun acc' -> >>= fun acc' ->
fold_m f acc' l' fold_m ~f ~init:acc' l'
end end
(** {2 Conversions} *) (** {2 Conversions} *)
@ -1054,7 +1055,7 @@ type 'a printer = Format.formatter -> 'a -> unit
type 'a random_gen = Random.State.t -> 'a type 'a random_gen = Random.State.t -> 'a
let random_len len g st = let random_len len g st =
init len (fun _ -> g st) init len ~f:(fun _ -> g st)
(*$T (*$T
random_len 10 CCInt.random_small (Random.State.make [||]) |> List.length = 10 random_len 10 CCInt.random_small (Random.State.make [||]) |> List.length = 10
@ -1076,7 +1077,7 @@ let random_choose l = match l with
let i = Random.State.int st len in let i = Random.State.int st len in
List.nth l i List.nth l i
let random_sequence l st = map (fun g -> g st) l let random_sequence l st = map l ~f:(fun g -> g st)
let to_seq l k = List.iter k l let to_seq l k = List.iter k l
let of_seq seq = let of_seq seq =

View file

@ -11,7 +11,7 @@ val is_empty : _ t -> bool
(** [is_empty l] returns [true] iff [l = []] (** [is_empty l] returns [true] iff [l = []]
@since 0.11 *) @since 0.11 *)
val map : ('a -> 'b) -> 'a t -> 'b t val map : f:('a -> 'b) -> 'a t -> 'b t
(** Safe version of map *) (** Safe version of map *)
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
@ -32,38 +32,38 @@ val cons_maybe : 'a option -> 'a t -> 'a t
val (@) : 'a t -> 'a t -> 'a t val (@) : 'a t -> 'a t -> 'a t
val filter : ('a -> bool) -> 'a t -> 'a t val filter : f:('a -> bool) -> 'a t -> 'a t
(** Safe version of {!List.filter} *) (** Safe version of {!List.filter} *)
val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
(** Safe version of [fold_right] *) (** Safe version of [fold_right] *)
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'a -> 'b t -> 'a
(** Fold until a stop condition via [('a, `Stop)] is (** Fold until a stop condition via [('a, `Stop)] is
indicated by the accumulator indicated by the accumulator
@since 0.8 *) @since 0.8 *)
val fold_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a list -> 'acc * 'b list val fold_map : f:('acc -> 'a -> 'acc * 'b) -> init:'acc -> 'a list -> 'acc * 'b list
(** [fold_map f acc l] is a [fold_left]-like function, but it also maps the (** [fold_map f acc l] is a [fold_left]-like function, but it also maps the
list to another list. list to another list.
@since 0.14 *) @since 0.14 *)
val fold_map2 : ('acc -> 'a -> 'b -> 'acc * 'c) -> 'acc -> 'a list -> 'b list -> 'acc * 'c list val fold_map2 : f:('acc -> 'a -> 'b -> 'acc * 'c) -> init:'acc -> 'a list -> 'b list -> 'acc * 'c list
(** [fold_map2] is to [fold_map] what [List.map2] is to [List.map]. (** [fold_map2] is to [fold_map] what [List.map2] is to [List.map].
@raise Invalid_argument if the lists do not have the same length @raise Invalid_argument if the lists do not have the same length
@since 0.16 *) @since 0.16 *)
val fold_filter_map : ('acc -> 'a -> 'acc * 'b option) -> 'acc -> 'a list -> 'acc * 'b list val fold_filter_map : f:('acc -> 'a -> 'acc * 'b option) -> init:'acc -> 'a list -> 'acc * 'b list
(** [fold_filter_map f acc l] is a [fold_left]-like function, but also (** [fold_filter_map f acc l] is a [fold_left]-like function, but also
generates a list of output in a way similar to {!filter_map} generates a list of output in a way similar to {!filter_map}
@since 0.17 *) @since 0.17 *)
val fold_flat_map : ('acc -> 'a -> 'acc * 'b list) -> 'acc -> 'a list -> 'acc * 'b list val fold_flat_map : f:('acc -> 'a -> 'acc * 'b list) -> init:'acc -> 'a list -> 'acc * 'b list
(** [fold_flat_map f acc l] is a [fold_left]-like function, but it also maps the (** [fold_flat_map f acc l] is a [fold_left]-like function, but it also maps the
list to a list of lists that is then [flatten]'d.. list to a list of lists that is then [flatten]'d..
@since 0.14 *) @since 0.14 *)
val init : int -> (int -> 'a) -> 'a t val init : int -> f:(int -> 'a) -> 'a t
(** Similar to {!Array.init} (** Similar to {!Array.init}
@since 0.6 *) @since 0.6 *)
@ -71,23 +71,23 @@ val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
val flat_map : ('a -> 'b t) -> 'a t -> 'b t val flat_map : f:('a -> 'b t) -> 'a t -> 'b t
(** Map and flatten at the same time (safe). Evaluation order is not guaranteed. *) (** Map and flatten at the same time (safe). Evaluation order is not guaranteed. *)
val flatten : 'a t t -> 'a t val flatten : 'a t t -> 'a t
(** Safe flatten *) (** Safe flatten *)
val product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val product : f:('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
(** Cartesian product of the two lists, with the given combinator *) (** Cartesian product of the two lists, with the given combinator *)
val fold_product : ('c -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c val fold_product : f:('c -> 'a -> 'b -> 'c) -> init:'c -> 'a t -> 'b t -> 'c
(** Fold on the cartesian product *) (** Fold on the cartesian product *)
val diagonal : 'a t -> ('a * 'a) t 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]) -> val partition_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) ->
'a list -> 'b list * 'c list 'a list -> 'b list * 'c list
(** [partition_map f l] maps [f] on [l] and gather results in lists: (** [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 = `Left y], adds [y] to the first list
@ -120,10 +120,10 @@ val take_drop : int -> 'a t -> 'a t * 'a t
(** [take_drop n l] returns [l1, l2] such that [l1 @ l2 = l] and (** [take_drop n l] returns [l1, l2] such that [l1 @ l2 = l] and
[length l1 = min (length l) n] *) [length l1 = min (length l) n] *)
val take_while : ('a -> bool) -> 'a t -> 'a t val take_while : f:('a -> bool) -> 'a t -> 'a t
(** @since 0.13 *) (** @since 0.13 *)
val drop_while : ('a -> bool) -> 'a t -> 'a t val drop_while : f:('a -> bool) -> 'a t -> 'a t
(** @since 0.13 *) (** @since 0.13 *)
val split : int -> 'a t -> 'a t * 'a t val split : int -> 'a t -> 'a t * 'a t
@ -142,43 +142,44 @@ val last_opt : 'a t -> 'a option
(** Last element. (** Last element.
@since 0.20 *) @since 0.20 *)
val find_pred : ('a -> bool) -> 'a t -> 'a option val find_pred : f:('a -> bool) -> 'a t -> 'a option
(** [find_pred p l] finds the first element of [l] that satisfies [p], (** [find_pred p l] finds the first element of [l] that satisfies [p],
or returns [None] if no element satisfies [p] or returns [None] if no element satisfies [p]
@since 0.11 *) @since 0.11 *)
val find_pred_exn : ('a -> bool) -> 'a t -> 'a val find_pred_exn : f:('a -> bool) -> 'a t -> 'a
(** Unsafe version of {!find_pred} (** Unsafe version of {!find_pred}
@raise Not_found if no such element is found @raise Not_found if no such element is found
@since 0.11 *) @since 0.11 *)
val find_map : ('a -> 'b option) -> 'a t -> 'b option val find_map : f:('a -> 'b option) -> 'a t -> 'b option
(** [find_map f l] traverses [l], applying [f] to each element. If for (** [find_map f l] traverses [l], applying [f] to each element. If for
some element [x], [f x = Some y], then [Some y] is returned. Otherwise some element [x], [f x = Some y], then [Some y] is returned. Otherwise
the call returns [None] the call returns [None]
@since 0.11 *) @since 0.11 *)
val find : ('a -> 'b option) -> 'a list -> 'b option (* TODO remove *)
val find : f:('a -> 'b option) -> 'a list -> 'b option
(** @deprecated since 0.11 in favor of {!find_map}, for the name is too confusing *) (** @deprecated since 0.11 in favor of {!find_map}, for the name is too confusing *)
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option val find_mapi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
(** Like {!find_map}, but also pass the index to the predicate function. (** Like {!find_map}, but also pass the index to the predicate function.
@since 0.11 *) @since 0.11 *)
val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option val findi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
(** @deprecated since 0.11 in favor of {!find_mapi}, name is too confusing (** @deprecated since 0.11 in favor of {!find_mapi}, name is too confusing
@since 0.3.4 *) @since 0.3.4 *)
val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option
(** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], (** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l],
and [p x] holds. Otherwise returns [None] *) and [p x] holds. Otherwise returns [None] *)
val remove : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t val remove : ?eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t
(** [remove ~x l] removes every instance of [x] from [l]. Tailrec. (** [remove ~key l] removes every instance of [key] from [l]. Tailrec.
@param eq equality function @param eq equality function
@since 0.11 *) @since 0.11 *)
val filter_map : ('a -> 'b option) -> 'a t -> 'b t val filter_map : f:('a -> 'b option) -> 'a t -> 'b t
(** Map and remove elements at the same time *) (** Map and remove elements at the same time *)
val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
@ -224,11 +225,11 @@ val group_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list list
(** {2 Indices} *) (** {2 Indices} *)
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t val mapi : f:(int -> 'a -> 'b) -> 'a t -> 'b t
val iteri : (int -> 'a -> unit) -> 'a t -> unit val iteri : f:(int -> 'a -> unit) -> 'a t -> unit
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b val foldi : f:('b -> int -> 'a -> 'b) -> init:'b -> 'a t -> 'b
(** Fold on list, with index *) (** Fold on list, with index *)
val get_at_idx : int -> 'a t -> 'a option val get_at_idx : int -> 'a t -> 'a option
@ -379,11 +380,11 @@ end
module Traverse(M : MONAD) : sig module Traverse(M : MONAD) : sig
val sequence_m : 'a M.t t -> 'a t M.t val sequence_m : 'a M.t t -> 'a t M.t
val fold_m : ('b -> 'a -> 'b M.t) -> 'b -> 'a t -> 'b M.t val fold_m : f:('b -> 'a -> 'b M.t) -> init:'b -> 'a t -> 'b M.t
val map_m : ('a -> 'b M.t) -> 'a t -> 'b t M.t val map_m : f:('a -> 'b M.t) -> 'a t -> 'b t M.t
val map_m_par : ('a -> 'b M.t) -> 'a t -> 'b t M.t val map_m_par : f:('a -> 'b M.t) -> 'a t -> 'b t M.t
(** Same as {!map_m} but [map_m_par f (x::l)] evaluates [f x] and (** Same as {!map_m} but [map_m_par f (x::l)] evaluates [f x] and
[f l] "in parallel" before combining their result (for instance [f l] "in parallel" before combining their result (for instance
in Lwt). *) in Lwt). *)

View file

@ -604,7 +604,7 @@ module Make(Key : KEY)
aux acc t aux acc t
(*$T (*$T
let l = CCList.(1 -- 10 |> map (fun x->x,x)) in \ let l = CCList.(1 -- 10 |> map ~f:(fun x->x,x)) in \
M.of_list l \ M.of_list l \
|> M.fold ~f:(fun acc x y -> (x,y)::acc) ~x:[] \ |> M.fold ~f:(fun acc x y -> (x,y)::acc) ~x:[] \
|> List.sort Pervasives.compare = l |> List.sort Pervasives.compare = l
@ -720,7 +720,7 @@ module Make(Key : KEY)
end end
(*$R (*$R
let m = M.of_list CCList.( (501 -- 1000) @ (500 -- 1) |> map (fun i->i,i)) in let m = M.of_list CCList.( (501 -- 1000) @ (500 -- 1) |> map ~f:(fun i->i,i)) in
assert_equal ~printer:CCInt.to_string 1000 (M.cardinal m); assert_equal ~printer:CCInt.to_string 1000 (M.cardinal m);
assert_bool "check all get" assert_bool "check all get"
(Sequence.for_all (fun i -> i = M.get_exn i m) Sequence.(1 -- 1000)); (Sequence.for_all (fun i -> i = M.get_exn i m) Sequence.(1 -- 1000));

View file

@ -361,7 +361,7 @@ module MakeFull(K : KEY) : S with type key = K.t = struct
with Not_found -> None with Not_found -> None
(*$T (*$T
let m = CCList.(0 -- 1000 |> map (fun i->i,i) |> M.of_list) in \ let m = CCList.(0 -- 1000 |> map ~f:(fun i->i,i) |> M.of_list) in \
List.for_all (fun i -> M.nth_exn i m = (i,i)) CCList.(0--1000) List.for_all (fun i -> M.nth_exn i m = (i,i)) CCList.(0--1000)
*) *)