@@ -26,7 +26,7 @@ module String : sig
26
26
val of-char : Char.t -> string
27
27
val of-length : length -> string
28
28
val append : string -> string -> string
29
- val concat : string list -> string
29
+ val concat : string ?-> string list -> string
30
30
val is-empty : string -> bool
31
31
val starts-with : string -> string -> bool
32
32
val ends-with : string -> string -> bool
@@ -38,6 +38,17 @@ module String : sig
38
38
val split-by : Char.t -> string -> string list
39
39
val lines : string -> string list
40
40
val index : Char.t -> string -> int option
41
+ val make : int -> Char.t -> string
42
+ val init : int -> (int -> Char.t) -> string
43
+ val get : int -> string -> Char.t option
44
+ val contains : string -> string -> bool
45
+ val trim : string -> string
46
+ val trim-start : string -> string
47
+ val trim-end : string -> string
48
+ val uppercase-ascii : string -> string
49
+ val lowercase-ascii : string -> string
50
+ val capitalize-ascii : string -> string
51
+ val uncapitalize-ascii : string -> string
41
52
% val byte-length : string -> int
42
53
% val sub-bytes : int -> int -> string -> string
43
54
end = struct
@@ -53,9 +64,22 @@ end = struct
53
64
let of-char = Char.to-string
54
65
let append s1 s2 = s1 ^ s2
55
66
56
- let-rec concat xs = match xs with
57
- | [] -> empty
58
- | s :: xs -> s ^ concat xs
67
+
68
+
69
+ let concat ?:s xs =
70
+ let s =
71
+ match s with
72
+ | None -> empty
73
+ | Some(s) -> s
74
+ in
75
+ let-rec sub xs =
76
+ match xs with
77
+ | [] -> empty
78
+ | [x] -> x
79
+ | x :: xs -> x ^ s ^ sub xs
80
+ in
81
+ sub xs
82
+
59
83
60
84
let is-empty s =
61
85
equal s empty
@@ -71,13 +95,12 @@ end = struct
71
95
(s-len >= p-len) &&&- (fun () -> equal (s |> sub (s-len - 1 - p-len) p-len) p)
72
96
73
97
let to-list s =
74
- let-rec go i acc = (match i with
75
- | 0 -> acc
76
- | _ -> go (i - 1) (Char.at (i - 1) s :: acc)) in
77
- go (length s) []
98
+ s
99
+ |> string-explode
100
+ |> List.map Char.of-codepoint
78
101
79
102
let of-list chars =
80
- chars |> List.map Char.to-string |> concat
103
+ chars |> List.map Char.to-string |> (fun slst -> concat slst)
81
104
82
105
let pow n s =
83
106
let-rec go i acc = if i == n then acc else go (i + 1) (acc ^ s) in
@@ -103,6 +126,176 @@ end = struct
103
126
104
127
let lines = split-by Char.newline
105
128
129
+
130
+ let-rec make n c =
131
+ if n <= 0 then
132
+ empty
133
+ else
134
+ Char.to-string c ^ make (n - 1) c
135
+
136
+
137
+ let init n f =
138
+ let-rec sub m f =
139
+ if m >= n then
140
+ empty
141
+ else
142
+ Char.to-string (f m) ^ sub (m + 1) f
143
+ in
144
+ sub 0 f
145
+
146
+
147
+ let get n str =
148
+ str
149
+ |> to-list
150
+ |> List.nth n
151
+
152
+
153
+
154
+
155
+ % Quick-Search
156
+ % こちらを参考に実装:https://www.m3tech.blog/entry/2020/09/28/120000
157
+ let contains s str =
158
+ % 検索する語と検索される語が先頭から一致するかどうかを判定する
159
+ % 一致しない場合は先頭の文字を渡す
160
+ let-rec search-and-get-next-char is-eq clst slst =
161
+ match (clst, slst) with
162
+ | ([], []) -> (is-eq, None)
163
+ | ([], s::_) -> (is-eq, Some(s))
164
+ | (_, []) -> (false, None)
165
+ | (c::cs, s::ss) -> (
166
+ if Char.equal c s && is-eq then
167
+ search-and-get-next-char true cs ss
168
+ else
169
+ search-and-get-next-char false cs ss
170
+ )
171
+ in
172
+
173
+ % 検索される語の先頭の文字が、検索する語の中で何番目にあたるかを調べる
174
+ % 検索される後の先頭の文字が、検索する語の中にない場合はNoneが返る
175
+ let-rec find-next-char-pos n n-opt c clst =
176
+ match clst with
177
+ | x::xs -> (
178
+ if Char.equal x c then
179
+ find-next-char-pos (n + 1) (Some n) c xs
180
+ else
181
+ find-next-char-pos (n + 1) None c xs
182
+ )
183
+ | [] -> n-opt
184
+ in
185
+
186
+ let-rec shift n lst =
187
+ if n <= 0 then
188
+ lst
189
+ else
190
+ match lst with
191
+ | [] -> []
192
+ | _::xs -> shift (n - 1) xs
193
+ in
194
+
195
+ let clst = to-list s in
196
+ let-rec sub l =
197
+ match search-and-get-next-char true clst l with
198
+ | (true, _) -> true
199
+ | (false, None) -> false
200
+ | (false, Some(c)) -> (
201
+ let n-opt = find-next-char-pos 0 None c clst in
202
+ let n =
203
+ match n-opt with
204
+ | Some(n) -> List.length clst - n
205
+ | None -> List.length clst + 1
206
+ in
207
+ let new-l = shift n l in
208
+ sub new-l
209
+ )
210
+ in
211
+ sub (to-list str)
212
+
213
+
214
+ let-rec space-len n clst =
215
+ match clst with
216
+ | c::xs -> (
217
+ if Char.is-space c then
218
+ space-len (n + 1) xs
219
+ else
220
+ n
221
+ )
222
+ | _ -> n
223
+
224
+ let trim str =
225
+ let len = length str in
226
+ let lst = to-list str in
227
+ let rev-lst = List.reverse lst in
228
+ let start-space-len = space-len 0 lst in
229
+ let end-space-len = space-len 0 rev-lst in
230
+ let len = len - start-space-len - end-space-len in
231
+ let len = if len < 0 then 0 else len in
232
+ sub start-space-len len str
233
+
234
+ let trim-start str =
235
+ let len = length str in
236
+ let lst = to-list str in
237
+ let start-space-len = space-len 0 lst in
238
+ let len = len - start-space-len in
239
+ sub start-space-len len str
240
+
241
+ let trim-end str =
242
+ let len = length str in
243
+ let lst = str |> to-list |> List.reverse in
244
+ let start-space-len = space-len 0 lst in
245
+ let len = len - start-space-len in
246
+ sub 0 len str
247
+
248
+
249
+ let uppercase-ascii str =
250
+ str
251
+ |> to-list
252
+ |> List.map (fun c -> (
253
+ let n = Char.to-codepoint c in
254
+ if 0x61 <= n && n <= 0x7A then
255
+ Char.of-codepoint (n - 0x20)
256
+ else
257
+ c
258
+ ))
259
+ |> of-list
260
+
261
+ let lowercase-ascii str =
262
+ str
263
+ |> to-list
264
+ |> List.map (fun c -> (
265
+ let n = Char.to-codepoint c in
266
+ if 0x41 <= n && n <= 0x5A then
267
+ Char.of-codepoint (n + 0x20)
268
+ else
269
+ c
270
+ ))
271
+ |> of-list
272
+
273
+ let capitalize-ascii str =
274
+ str
275
+ |> to-list
276
+ |> List.mapi (fun i c -> (
277
+ let n = Char.to-codepoint c in
278
+ if i == 0 && 0x61 <= n && n <= 0x7A then
279
+ Char.of-codepoint (n - 0x20)
280
+ else
281
+ c
282
+ ))
283
+ |> of-list
284
+
285
+ let uncapitalize-ascii str =
286
+ str
287
+ |> to-list
288
+ |> List.mapi (fun i c -> (
289
+ let n = Char.to-codepoint c in
290
+ if i == 0 && 0x41 <= n && n <= 0x5A then
291
+ Char.of-codepoint (n + 0x20)
292
+ else
293
+ c
294
+ ))
295
+ |> of-list
296
+
297
+
298
+
106
299
let index c s =
107
300
let cs = to-list s in
108
301
let-rec aux cs acc = match cs with
0 commit comments