-
Notifications
You must be signed in to change notification settings - Fork 89
Expand file tree
/
Copy pathCCArrayLabels.mli
More file actions
360 lines (275 loc) · 12.9 KB
/
Copy pathCCArrayLabels.mli
File metadata and controls
360 lines (275 loc) · 12.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
(* This file is free software, part of containers. See file "license" for more details. *)
(** Array utils (Labeled version of {!CCArray}) *)
type 'a iter = ('a -> unit) -> unit
(** Fast internal iterator.
@since 2.8 *)
type 'a gen = unit -> 'a option
type 'a equal = 'a -> 'a -> bool
type 'a ord = 'a -> 'a -> int
type 'a random_gen = Random.State.t -> 'a
type 'a printer = Format.formatter -> 'a -> unit
(** {2 Arrays} *)
[@@@if ge 4.8]
include module type of ArrayLabels with module Floatarray = Array.Floatarray
(** @inline
{{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html} Documentation for the standard Array module}*)
[@@@elif ge 4.6]
include module type of ArrayLabels with module Floatarray = Array.Floatarray
(** @inline
{{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html} Documentation for the standard Array module}*)
type 'a t = 'a array
[@@@else_]
include module type of ArrayLabels
(** @inline
{{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html} Documentation for the standard Array module}*)
module Floatarray = CCArray.Floatarray
type 'a t = 'a array
[@@@endif]
val empty : 'a t
(** [empty] is the empty array, physically equal to [[||]]. *)
val equal : 'a equal -> 'a t equal
(** [equal eq a1 a2] is [true] if the lengths of [a1] and [a2] are the same
and if their corresponding elements test equal, using [eq]. *)
val compare : 'a ord -> 'a t ord
(** [compare cmp a1 a2] compares arrays [a1] and [a2] using the function comparison [cmp]. *)
val swap : 'a t -> int -> int -> unit
(** [swap a i j] swaps elements at indices [i] and [j].
@since 1.4 *)
val get_safe : 'a t -> int -> 'a option
(** [get_safe a i] returns [Some a.(i)] if [i] is a valid index.
@since 0.18 *)
val map_inplace : f:('a -> 'a) -> 'a t -> unit
(** [map_inplace ~f a] replace all elements of [a] by its image by [f].
@since 3.8 *)
val fold : f:('a -> 'b -> 'a) -> init:'a -> 'b t -> 'a
(** [fold ~f ~init a] computes [f (… (f (f init a.(0)) a.(1)) …) a.(n-1)],
where [n] is the length of the array [a].
Same as {!ArrayLabels.fold_left} *)
val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a
(** [foldi ~f ~init a] is just like {!fold}, but it also passes in the index
of each element as the second argument to the folded function [f]. *)
val fold_while :
f:('a -> 'b -> 'a * [ `Stop | `Continue ]) -> init:'a -> 'b t -> 'a
(** [fold_while ~f ~init a] folds left on array [a] until a stop condition via [('a, `Stop)]
is indicated by the accumulator.
@since 0.8 *)
val fold_map : f:('acc -> 'a -> 'acc * 'b) -> init:'acc -> 'a t -> 'acc * 'b t
(** [fold_map ~f ~init a] is a [fold_left]-like function, but it also maps the
array to another array.
@since 1.2, but only
@since 2.1 with labels *)
val scan_left : f:('acc -> 'a -> 'acc) -> init:'acc -> 'a t -> 'acc t
(** [scan_left ~f ~init a] returns the array
[ [|init; f init x0; f (f init a.(0)) a.(1); …|] ].
@since 1.2, but only
@since 2.1 with labels *)
val reverse_in_place : 'a t -> unit
(** [reverse_in_place a] reverses the array [a] in place. *)
val sorted : f:('a -> 'a -> int) -> 'a t -> 'a array
(** [sorted ~f a] makes a copy of [a] and sorts it with [f].
@since 1.0 *)
val sort_indices : f:('a -> 'a -> int) -> 'a t -> int array
(** [sort_indices ~f a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the index at which the [i]-th element of [sorted f a]
appears in [a]. [a] is not modified.
In other words, [map (fun i -> a.(i)) (sort_indices f a) = sorted f a].
[sort_indices] yields the inverse permutation of {!sort_ranking}.
@since 1.0 *)
val sort_ranking : f:('a -> 'a -> int) -> 'a t -> int array
(** [sort_ranking ~f a] returns a new array [b], with the same length as [a],
such that [b.(i)] is the index at which the [i]-th element of [a] appears
in [sorted f a]. [a] is not modified.
In other words, [map (fun i -> (sorted f a).(i)) (sort_ranking f a) = a].
[sort_ranking] yields the inverse permutation of {!sort_indices}.
In the absence of duplicate elements in [a], we also have
[lookup_exn a.(i) (sorted a) = (sorted_ranking a).(i)].
@since 1.0 *)
val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
(** [mem ~eq x a] return true if x is present in [a]. Linear time.
@since 3.0
*)
val find_map : f:('a -> 'b option) -> 'a t -> 'b option
(** [find_map ~f a] returns [Some y] if there is an element [x] such
that [f x = Some y]. Otherwise returns [None].
@since 1.3, but only
@since 2.1 with labels *)
val find_map_i : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
(** [find_map_i ~f a] is like {!find_map}, but the index of the element is also passed
to the predicate function [f].
@since 1.3, but only
@since 2.1 with labels *)
val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option
(** [find_idx ~f a] returns [Some (i,x)] where [x] is the [i]-th element of [a],
and [f x] holds. Otherwise returns [None].
@since 0.3.4 *)
val lookup : cmp:('a ord[@keep_label]) -> key:'a -> 'a t -> int option
(** [lookup ~cmp ~key a] lookups the index of some key [key] in a sorted array [a].
Undefined behavior if the array [a] is not sorted wrt [cmp].
Complexity: [O(log (n))] (dichotomic search).
@return [None] if the key [key] is not present, or
[Some i] ([i] the index of the key) otherwise. *)
val lookup_exn : cmp:('a ord[@keep_label]) -> key:'a -> 'a t -> int
(** [lookup_exn ~cmp ~key a] is like {!lookup}, but
@raise Not_found if the key [key] is not present. *)
val bsearch :
cmp:(('a -> 'a -> int)[@keep_label]) ->
key:'a ->
'a t ->
[ `All_lower | `All_bigger | `Just_after of int | `Empty | `At of int ]
(** [bsearch ~cmp ~key a] finds the index of the object [key] in the array [a],
provided [a] is {b sorted} using [cmp]. If the array is not sorted,
the result is not specified (may raise Invalid_argument).
Complexity: [O(log n)] where n is the length of the array [a]
(dichotomic search).
@return
- [`At i] if [cmp a.(i) key = 0] (for some i).
- [`All_lower] if all elements of [a] are lower than [key].
- [`All_bigger] if all elements of [a] are bigger than [key].
- [`Just_after i] if [a.(i) < key < a.(i+1)].
- [`Empty] if the array [a] is empty.
@raise Invalid_argument if the array is found to be unsorted w.r.t [cmp].
@since 0.13 *)
val for_all2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** [for_all2 ~f [|a1; …; an|] [|b1; …; bn|]] is [true] if each pair of elements [ai bi]
satisfies the predicate [f].
That is, it returns [(f a1 b1) && (f a2 b2) && … && (f an bn)].
@raise Invalid_argument if arrays have distinct lengths.
Allow different types.
@since 0.20 *)
val exists2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** [exists2 ~f [|a1; …; an|] [|b1; …; bn|]] is [true] if any pair of elements [ai bi]
satisfies the predicate [f].
That is, it returns [(f a1 b1) || (f a2 b2) || … || (f an bn)].
@raise Invalid_argument if arrays have distinct lengths.
Allow different types.
@since 0.20 *)
val fold2 : f:('acc -> 'a -> 'b -> 'acc) -> init:'acc -> 'a t -> 'b t -> 'acc
(** [fold2 ~f ~init a b] fold on two arrays [a] and [b] stepwise.
It computes [f (… (f init a1 b1) …) an bn].
@raise Invalid_argument if [a] and [b] have distinct lengths.
@since 0.20 *)
val iter2 : f:('a -> 'b -> unit) -> 'a t -> 'b t -> unit
(** [iter2 ~f a b] iterates on the two arrays [a] and [b] stepwise.
It is equivalent to [f a0 b0; …; f a.(length a - 1) b.(length b - 1); ()].
@raise Invalid_argument if [a] and [b] have distinct lengths.
@since 0.20 *)
val shuffle : 'a t -> unit
(** [shuffle a] randomly shuffles the array [a], in place. *)
val shuffle_with : Random.State.t -> 'a t -> unit
(** [shuffle_with rs a] randomly shuffles the array [a] (like {!shuffle}) but a specialized random
state [rs] is used to control the random numbers being produced during shuffling (for reproducibility). *)
val random_choose : 'a t -> 'a random_gen
(** [random_choose a rs] randomly chooses an element of [a].
@raise Not_found if the array/slice is empty. *)
val to_string : ?sep:string -> ('a -> string) -> 'a array -> string
(** [to_string ~sep item_to_string a] print [a] to a string using [sep] as a separator
between elements of [a].
@since 2.7 *)
val to_iter : 'a t -> 'a iter
(** [to_iter a] returns an [iter] of the elements of an array [a].
The input array [a] is shared with the sequence and modification of it will result
in modification of the iterator.
@since 2.8 *)
val to_seq : 'a t -> 'a Seq.t
(** [to_seq a] returns a [Seq.t] of the elements of an array [a].
The input array [a] is shared with the sequence and modification of it will result
in modification of the sequence.
Renamed from [to_std_seq] since 3.0.
@since 3.0
*)
val to_gen : 'a t -> 'a gen
(** [to_gen a] returns a [gen] of the elements of an array [a]. *)
(** {2 IO} *)
val pp :
?pp_start:unit printer ->
?pp_stop:unit printer ->
?pp_sep:unit printer ->
'a printer ->
'a t printer
(** [pp ~pp_start ~pp_stop ~pp_sep pp_item ppf a] formats the array [a] on [ppf].
Each element is formatted with [pp_item], [pp_start] is called at the beginning,
[pp_stop] is called at the end, [pp_sep] is called between each elements.
By defaults [pp_start] and [pp_stop] does nothing and [pp_sep] defaults to
(fun out -> Format.fprintf out ",@ "). *)
val pp_i :
?pp_start:unit printer ->
?pp_stop:unit printer ->
?pp_sep:unit printer ->
(int -> 'a printer) ->
'a t printer
(** [pp_i ~pp_start ~pp_stop ~pp_sep pp_item ppf a] prints the array [a] on [ppf].
The printing function [pp_item] is giving both index and element.
[pp_start] is called at the beginning,
[pp_stop] is called at the end, [pp_sep] is called between each elements.
By defaults [pp_start] and [pp_stop] does nothing and [pp_sep] defaults to
(fun out -> Format.fprintf out ",@ "). *)
val map2 : f:('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
(** [map2 ~f a b] applies function [f] to all elements of [a] and [b],
and builds an array with the results returned by [f]:
[[| f a.(0) b.(0); …; f a.(length a - 1) b.(length b - 1)|]].
@raise Invalid_argument if [a] and [b] have distinct lengths.
@since 0.20 *)
val rev : 'a t -> 'a t
(** [rev a] copies the array [a] and reverses it in place.
@since 0.20 *)
val filter : f:('a -> bool) -> 'a t -> 'a t
(** [filter ~f a] filters elements out of the array [a]. Only the elements satisfying
the given predicate [f] will be kept. *)
val filter_map : f:('a -> 'b option) -> 'a t -> 'b t
(** [filter_map ~f [|a1; …; an|]] calls [(f a1) … (f an)] and returns an array [b] consisting
of all elements [bi] such as [f ai = Some bi]. When [f] returns [None], the corresponding
element of [a] is discarded. *)
val monoid_product : f:('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
(** [monoid_product ~f a b] passes all combinaisons of tuples from the two arrays [a] and [b]
to the function [f].
@since 2.8 *)
val flat_map : f:('a -> 'b t) -> 'a t -> 'b array
(** [flat_map ~f a] transforms each element of [a] into an array, then flattens. *)
val except_idx : 'a t -> int -> 'a list
(** [except_idx a i] removes the element of [a] at given index [i], and returns
the list of the other elements. *)
val random : 'a random_gen -> 'a t random_gen
val random_non_empty : 'a random_gen -> 'a t random_gen
val random_len : int -> 'a random_gen -> 'a t random_gen
(** {2 Generic Functions} *)
module type MONO_ARRAY = sig
type elt
type t
val length : t -> int
val get : t -> int -> elt
val set : t -> int -> elt -> unit
end
val sort_generic :
(module MONO_ARRAY with type t = 'arr and type elt = 'elt) ->
cmp:(('elt -> 'elt -> int)[@keep_label]) ->
'arr ->
unit
(** [sort_generic (module M) ~cmp a] sorts the array [a], without allocating (eats stack space though).
Performance might be lower than {!Array.sort}.
@since 0.14 *)
(** {3 Infix Operators}
It is convenient to {!open CCArray.Infix} to access the infix operators
without cluttering the scope too much.
@since 2.7 *)
module Infix : sig
val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
(** [a >>= f] is the infix version of {!flat_map}. *)
val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t
(** [a >>| f] is the infix version of {!map}.
@since 0.8 *)
val ( >|= ) : 'a t -> ('a -> 'b) -> 'b t
(** [a >|= f] is the infix version of {!map}.
@since 0.8 *)
val ( -- ) : int -> int -> int t
(** [x -- y] creates an array containing integers in the range [x .. y]. Bounds included. *)
val ( --^ ) : int -> int -> int t
(** [x --^ y] creates an array containing integers in the range [x .. y]. Right bound excluded.
@since 0.17 *)
[@@@if ge 4.8]
include CCShims_syntax.LET with type 'a t := 'a array
(** Let operators on OCaml >= 4.08.0, nothing otherwise
@since 2.8
@inline *)
[@@@endif]
end
include module type of Infix