-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathlist2.ml
More file actions
212 lines (171 loc) · 3.51 KB
/
list2.ml
File metadata and controls
212 lines (171 loc) · 3.51 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
open Pervasives2
let pure_bind xs f =
List.map f xs
let pure x =
[x]
let bind xs f =
List.map f xs
|> List.concat
let concat_map f xs =
bind xs f
let maximum =
function
| [] ->
None
| head :: tail ->
Some (List.fold_left max head tail)
let repeat n x =
let rec helper k acc =
if k <= 0 then
acc
else
helper (k - 1) (x :: acc)
in
helper n []
let sequence mxs =
List.fold_right
( fun xs acc ->
bind xs @@ fun x ->
pure_bind acc @@ fun ys ->
x :: ys
)
mxs
([[]])
let filter_somes xs =
List.filter_map Fun.id xs
let intersperse sep xs =
let rec helper acc =
function
| [] -> List.rev acc
| [x] -> List.rev (x :: acc)
| head :: tail -> helper (sep :: head :: acc) tail
in
helper [] xs
let range ~low ~high =
ListLabels.init ~len:(high - low + 1) ~f:((+) low)
let remove_first y xs =
let rec helper acc =
function
| [] ->
List.rev acc
| head :: tail ->
if head = y then
List.rev_append acc tail
else
helper (head :: acc) tail
in
helper [] xs
let permutations ys =
(* Source: https://stackoverflow.com/a/40099411 *)
let rec permutations' xs =
if xs = [] then
[[]]
else
bind xs @@ fun x ->
bind (permutations' (remove_first x xs)) @@ fun permutation ->
[ x :: permutation ]
in
List.sort_uniq compare (permutations' ys)
let map3 f xs1 xs2 xs3 =
List.map2
(fun (x1, x2) x3 -> f x1 x2 x3)
(List.combine xs1 xs2)
xs3
let hd_opt xs =
match xs with
| [] ->
None
| head :: _ ->
Some head
let tl_opt xs =
match xs with
| [] ->
None
| _ :: tail ->
Some tail
let uncons xs =
match xs with
| [] ->
None
| head :: tail ->
Some (head, tail)
let is_empty xs =
match xs with
| [] ->
true
| _ :: _ ->
false
let rec transpose xss =
if List.for_all is_empty xss then
[]
else
List.filter_map hd_opt xss
:: transpose (List.map (tl_opt >> Option2.with_default []) xss)
let collapse_equal xs =
match xs with
| [] ->
None
| head :: tail ->
if List.for_all (fun x -> x = head) tail then
Some head
else
None
let index_left xs =
List.mapi (fun i x -> (i, x)) xs
let index_right xs =
List.mapi (fun i x -> (x, i)) xs
let rec find_map f xs =
match xs with
| [] ->
None
| head :: tail ->
begin match f head with
| Some x ->
Some x
| None ->
find_map f tail
end
let sum xs =
List.fold_left ((+)) 0 xs
let fsum xs =
List.fold_left ((+.)) 0.0 xs
let average xs =
let len =
List.length xs
in
if Int.equal len 0 then
None
else
Some (fsum xs /. float_of_int len)
let take n xs =
let rec helper acc n xs =
if n <= 0 then
List.rev acc
else
match xs with
| [] ->
List.rev acc
| head :: tail ->
helper (head :: acc) (n - 1) tail
in
helper [] n xs
let rec drop n xs =
if n <= 0 then
xs
else
match xs with
| [] ->
[]
| _ :: tail ->
drop (n - 1) tail
let cartesian_product xs ys =
concat_map (fun x -> List.map (fun y -> (x, y)) ys) xs
let count pred xs =
let rec helper acc =
function
| [] ->
acc
| head :: tail ->
helper (if pred head then acc + 1 else acc) tail
in
helper 0 xs