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
module Array = struct
external caml_make_vect : int -> 'a -> 'a array = "caml_make_vect"
let length = Stdlib.Array.length
let unsafe_get = Stdlib.Array.unsafe_get
let unsafe_set = Stdlib.Array.unsafe_set
let sub = Stdlib.ArrayLabels.sub
let create ~len x =
try caml_make_vect len x
with Invalid_argument _ ->
failwith @@ Printf.sprintf "Array.create ~len:%d: invalid length" len
let filter_mapi ~f t =
let r = ref [||] in
let k = ref 0 in
for i = 0 to length t - 1 do
match f i (unsafe_get t i) with
| None -> ()
| Some a ->
if !k = 0 then r := create ~len:(length t) a;
unsafe_set !r !k a;
incr k
done;
if !k = length t then !r else if !k > 0 then sub ~pos:0 ~len:!k !r else [||]
let reduce ~init ~f t =
let r = ref init in
for i = 0 to Stdlib.Array.length t - 1 do
r := f !r (Stdlib.Array.unsafe_get t i)
done;
!r
let map = Stdlib.ArrayLabels.map
let filter_map ~f t = (filter_mapi t ~f:(fun _i a -> f a) [@nontail])
let map_and_join ~sep ~f strings =
let len = Stdlib.Array.length strings in
let rec run i acc =
if i >= len then acc
else if i = len - 1 then acc ^ f strings.(i)
else run (i + 1) (acc ^ f strings.(i) ^ sep)
in
run 0 ""
end
module String = struct
let get = Stdlib.String.get
let trim = Stdlib.String.trim
let length = Stdlib.String.length
let starts_with ~prefix str =
let len_prefix = String.length prefix in
let len_str = String.length str in
let rec compare_prefix i =
i = len_prefix
|| (i < len_str && prefix.[i] = str.[i] && compare_prefix (i + 1))
in
compare_prefix 0
end
module Int = struct
let to_string v = Stdlib.string_of_int v
end
module Float = struct
let to_string t =
if Stdlib.Float.equal (Stdlib.Float.round t) t then
t |> int_of_float |> string_of_int
else Printf.sprintf "%g" t
end
module Option = struct
let get_with_default default opt =
match opt with Some x -> x | None -> default
let map_with_default opt default fn =
match opt with Some x -> fn x | None -> default
let map ~f opt = match opt with Some x -> Some (f x) | None -> None
end