1 | |
---|
2 | let rec make a n = |
---|
3 | if n = 0 then [] |
---|
4 | else a :: (make a (n-1)) |
---|
5 | |
---|
6 | let index_of x = |
---|
7 | let rec aux i = function |
---|
8 | | [] -> raise Not_found |
---|
9 | | y :: l -> if y = x then i else aux (i+1) l |
---|
10 | in |
---|
11 | aux 0 |
---|
12 | |
---|
13 | let foldi f a = |
---|
14 | let rec aux i res = function |
---|
15 | | [] -> res |
---|
16 | | e :: l -> aux (i+1) (f i res e) l |
---|
17 | in |
---|
18 | aux 0 a |
---|
19 | |
---|
20 | let iteri f l = |
---|
21 | let rec aux i = function |
---|
22 | | [] -> () |
---|
23 | | e :: l -> f i e ; aux (i+1) l |
---|
24 | in |
---|
25 | aux 0 l |
---|
26 | |
---|
27 | let mapi f l = |
---|
28 | let rec aux i = function |
---|
29 | | [] -> [] |
---|
30 | | e :: l -> (f i e) :: (aux (i+1) l) |
---|
31 | in |
---|
32 | aux 0 l |
---|
33 | |
---|
34 | let rec last = function |
---|
35 | | [] -> raise Not_found |
---|
36 | | [a] -> a |
---|
37 | | _ :: l -> last l |
---|
38 | |
---|
39 | (* [split a i] splits the list a in two lists: one with the elements |
---|
40 | up until the [i]th (exclusive) and one with the rest. *) |
---|
41 | |
---|
42 | let rec split l i = |
---|
43 | if i = 0 then ([], l) |
---|
44 | else |
---|
45 | let (l1, l2) = split (List.tl l) (i-1) in |
---|
46 | ((List.hd l) :: l1, l2) |
---|
47 | |
---|
48 | (* [split_last l] returns the list [l] without its last element and its last |
---|
49 | element. Raises Invalid_argument "MiscPottier.split_last" if the list is |
---|
50 | empty. *) |
---|
51 | |
---|
52 | let split_last l = match split l ((List.length l) - 1) with |
---|
53 | | l', last :: _ -> (l', last) |
---|
54 | | _ -> raise (Invalid_argument "MiscPottier.split_last") |
---|
55 | |
---|
56 | let rec update_list_assoc a b = function |
---|
57 | | [] -> [] |
---|
58 | | (a', b') :: l -> |
---|
59 | if a' = a then (a, b) :: l else (a', b') :: (update_list_assoc a b l) |
---|
60 | |
---|
61 | (* Pasted from Pottier's PP compiler *) |
---|
62 | |
---|
63 | let rec combine xs1 xs2 = |
---|
64 | match xs1, xs2 with |
---|
65 | | [], _ |
---|
66 | | _, [] -> |
---|
67 | [] |
---|
68 | | x1 :: xs1, x2 :: xs2 -> |
---|
69 | (x1, x2) :: combine xs1 xs2 |
---|
70 | |
---|
71 | let rec subtract xs1 xs2 = |
---|
72 | match xs1, xs2 with |
---|
73 | | [], _ -> |
---|
74 | [] |
---|
75 | | _, [] -> |
---|
76 | xs1 |
---|
77 | | _ :: xs1, _ :: xs2 -> |
---|
78 | subtract xs1 xs2 |
---|
79 | |
---|
80 | let mirror l = |
---|
81 | List.map (fun (x, y) -> (y, x)) l |
---|
82 | |
---|
83 | let length l = |
---|
84 | Int32.of_int (List.length l) |
---|
85 | |
---|
86 | let rec prefix k l = |
---|
87 | match k, l with |
---|
88 | | 0, _ |
---|
89 | | _, [] -> |
---|
90 | [] |
---|
91 | | _, x :: xs -> |
---|
92 | x :: prefix (k - 1) xs |
---|
93 | |
---|
94 | let memoize f = |
---|
95 | let table = Hashtbl.create 131 in |
---|
96 | fun key -> |
---|
97 | try |
---|
98 | Hashtbl.find table key |
---|
99 | with Not_found -> |
---|
100 | let data = f key in |
---|
101 | Hashtbl.add table key data; |
---|
102 | data |
---|
103 | |
---|
104 | let filter_map filter map = |
---|
105 | let rec aux = function |
---|
106 | | [] -> [] |
---|
107 | | e :: l -> (if filter e then [map e] else []) @ (aux l) |
---|
108 | in |
---|
109 | aux |
---|
110 | |
---|
111 | let string_of_list sep f = |
---|
112 | let rec aux = function |
---|
113 | | [] -> "" |
---|
114 | | [e] -> f e |
---|
115 | | e :: l -> (f e) ^ sep ^ (aux l) |
---|
116 | in |
---|
117 | aux |
---|