mayak 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,449 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ module Mayak
5
+ module Monads
6
+ module Maybe
7
+ extend T::Sig
8
+ extend T::Generic
9
+ extend T::Helpers
10
+
11
+ abstract!
12
+ sealed!
13
+
14
+ Value = type_member
15
+
16
+ sig {
17
+ abstract
18
+ .type_parameters(:NewValue)
19
+ .params(blk: T.proc.params(arg0: Value).returns(T.type_parameter(:NewValue)))
20
+ .returns(Maybe[T.type_parameter(:NewValue)])
21
+ }
22
+ def map(&blk)
23
+ end
24
+
25
+ sig {
26
+ abstract
27
+ .type_parameters(:NewValue)
28
+ .params(
29
+ blk: T.proc.params(arg0: Value).returns(Maybe[T.type_parameter(:NewValue)])
30
+ )
31
+ .returns(Maybe[T.type_parameter(:NewValue)])
32
+ }
33
+ def flat_map(&blk)
34
+ end
35
+
36
+ sig {
37
+ abstract
38
+ .params(blk: T.proc.params(arg0: Value).returns(T::Boolean))
39
+ .returns(Maybe[Value])
40
+ }
41
+ def filter(&blk)
42
+ end
43
+
44
+ sig { abstract.returns(T::Boolean) }
45
+ def some?
46
+ end
47
+
48
+ sig { abstract.returns(T::Boolean) }
49
+ def none?
50
+ end
51
+
52
+ sig { abstract.params(value: Value).returns(Value) }
53
+ def value_or(value)
54
+ end
55
+
56
+ sig {
57
+ abstract
58
+ .params(blk: T.proc.params(arg0: Value).void)
59
+ .returns(Maybe[Value])
60
+ }
61
+ def tee(&blk)
62
+ end
63
+
64
+ sig {
65
+ abstract
66
+ .type_parameters(:Result)
67
+ .params(fallback: T.type_parameter(:Result), blk: T.proc.params(arg0: Value).returns(T.type_parameter(:Result)))
68
+ .returns(T.type_parameter(:Result))
69
+ }
70
+ def either(fallback, &blk)
71
+ end
72
+
73
+ sig {
74
+ abstract
75
+ .type_parameters(:Failure)
76
+ .params(failure: T.type_parameter(:Failure))
77
+ .returns(Mayak::Monads::Result[T.type_parameter(:Failure), Value])
78
+ }
79
+ def to_result(failure)
80
+ end
81
+
82
+ sig { abstract.params(error: StandardError).returns(Mayak::Monads::Try[Value]) }
83
+ def to_try(error)
84
+ end
85
+
86
+ sig(:final) {
87
+ type_parameters(:NewValue)
88
+ .params(new_value: T.type_parameter(:NewValue))
89
+ .returns(Maybe[T.type_parameter(:NewValue)])
90
+ }
91
+ def as(new_value)
92
+ map { |_| new_value }
93
+ end
94
+
95
+ sig { abstract.params(value: Value).returns(Maybe[Value]) }
96
+ def recover(value)
97
+ end
98
+
99
+ sig(:final) { params(another: Mayak::Monads::Maybe[T.untyped]).returns(T::Boolean) }
100
+ def ==(another)
101
+ case self
102
+ when Mayak::Monads::Maybe::Some
103
+ case another
104
+ when Mayak::Monads::Maybe::Some then T.unsafe(self.value) == another.value
105
+ when Mayak::Monads::Maybe::None then false
106
+ else T.absurd(another)
107
+ end
108
+ when Mayak::Monads::Maybe::None
109
+ case another
110
+ when Mayak::Monads::Maybe::Some then false
111
+ when Mayak::Monads::Maybe::None then true
112
+ else T.absurd(another)
113
+ end
114
+ else
115
+ T.absurd(self)
116
+ end
117
+ end
118
+
119
+ sig {
120
+ type_parameters(:Value)
121
+ .params(results: T::Array[Mayak::Monads::Maybe[T.type_parameter(:Value)]])
122
+ .returns(Mayak::Monads::Maybe[T::Array[T.type_parameter(:Value)]])
123
+ }
124
+ def self.sequence(results)
125
+ init = T.let(Maybe::Some.new([]), Maybe[T::Array[T.type_parameter(:Value)]])
126
+ results.reduce(init) do |result, element|
127
+ result.flat_map do |array|
128
+ element.map { |value| array + [value] }
129
+ end
130
+ end
131
+ end
132
+
133
+ sig {
134
+ type_parameters(:Value)
135
+ .params(value: T.type_parameter(:Value), blk: T.proc.returns(T::Boolean))
136
+ .returns(Mayak::Monads::Maybe[T.type_parameter(:Value)])
137
+ }
138
+ def self.check(value, &blk)
139
+ if blk.call
140
+ Mayak::Monads::Maybe::Some[T.type_parameter(:Value)].new(value)
141
+ else
142
+ Mayak::Monads::Maybe::None[T.type_parameter(:Value)].new
143
+ end
144
+ end
145
+
146
+ sig { params(blk: T.proc.returns(T::Boolean)).returns(Mayak::Monads::Maybe[NilClass]) }
147
+ def self.guard(&blk)
148
+ check(nil, &blk)
149
+ end
150
+
151
+ class Some
152
+ extend T::Sig
153
+ extend T::Generic
154
+ extend T::Helpers
155
+
156
+ final!
157
+
158
+ Value = type_member
159
+
160
+ include ::Mayak::Monads::Maybe
161
+
162
+ sig(:final) { params(value: Value).void }
163
+ def initialize(value)
164
+ @value = T.let(value, Value)
165
+ end
166
+
167
+ sig(:final) {
168
+ override
169
+ .type_parameters(:NewValue)
170
+ .params(blk: T.proc.params(arg0: Value).returns(T.type_parameter(:NewValue)))
171
+ .returns(Maybe[T.type_parameter(:NewValue)])
172
+ }
173
+ def map(&blk)
174
+ Mayak::Monads::Maybe::Some.new(blk.call(@value))
175
+ end
176
+
177
+ sig(:final) {
178
+ override
179
+ .type_parameters(:NewValue)
180
+ .params(blk: T.proc.params(arg0: Value).returns(Maybe[T.type_parameter(:NewValue)]))
181
+ .returns(Maybe[T.type_parameter(:NewValue)])
182
+ }
183
+ def flat_map(&blk)
184
+ blk.call(@value)
185
+ end
186
+
187
+ sig(:final) {
188
+ override
189
+ .params(blk: T.proc.params(arg0: Value).returns(T::Boolean))
190
+ .returns(Maybe[Value])
191
+ }
192
+ def filter(&blk)
193
+ if blk.call(@value)
194
+ self
195
+ else
196
+ Mayak::Monads::Maybe::None[Value].new
197
+ end
198
+ end
199
+
200
+ sig(:final) { returns(Value) }
201
+ def value
202
+ @value
203
+ end
204
+
205
+ sig(:final) { override.returns(T::Boolean) }
206
+ def some?
207
+ true
208
+ end
209
+
210
+ sig(:final) { override.returns(T::Boolean) }
211
+ def none?
212
+ false
213
+ end
214
+
215
+ sig(:final) { override.params(value: Value).returns(Value) }
216
+ def value_or(value)
217
+ @value
218
+ end
219
+
220
+ sig(:final) {
221
+ override
222
+ .params(blk: T.proc.params(arg0: Value).void)
223
+ .returns(Maybe[Value])
224
+ }
225
+ def tee(&blk)
226
+ blk.call(@value)
227
+ self
228
+ end
229
+
230
+ sig(:final) {
231
+ override
232
+ .type_parameters(:Result)
233
+ .params(fallback: T.type_parameter(:Result), blk: T.proc.params(arg0: Value).returns(T.type_parameter(:Result)))
234
+ .returns(T.type_parameter(:Result))
235
+ }
236
+ def either(fallback, &blk)
237
+ blk.call(@value)
238
+ end
239
+
240
+ sig(:final) {
241
+ override
242
+ .type_parameters(:Failure)
243
+ .params(failure: T.type_parameter(:Failure))
244
+ .returns(Mayak::Monads::Result[T.type_parameter(:Failure), Value])
245
+ }
246
+ def to_result(failure)
247
+ Mayak::Monads::Result::Success[T.type_parameter(:Failure), Value].new(@value)
248
+ end
249
+
250
+ sig(:final) { override.params(error: StandardError).returns(Mayak::Monads::Try[Value]) }
251
+ def to_try(error)
252
+ Mayak::Monads::Try::Success.new(@value)
253
+ end
254
+
255
+ sig(:final) { override.params(value: Value).returns(Maybe[Value]) }
256
+ def recover(value)
257
+ self
258
+ end
259
+ end
260
+
261
+ class None
262
+ extend T::Sig
263
+ extend T::Generic
264
+ extend T::Helpers
265
+
266
+ final!
267
+
268
+ Value = type_member
269
+
270
+ include Mayak::Monads::Maybe
271
+
272
+ sig(:final) {
273
+ override
274
+ .type_parameters(:NewValue)
275
+ .params(blk: T.proc.params(arg0: Value).returns(T.type_parameter(:NewValue)))
276
+ .returns(Maybe[T.type_parameter(:NewValue)])
277
+ }
278
+ def map(&blk)
279
+ T.cast(
280
+ self,
281
+ Maybe[T.type_parameter(:NewValue)]
282
+ )
283
+ end
284
+
285
+ sig(:final) {
286
+ override
287
+ .type_parameters(:NewValue)
288
+ .params(blk: T.proc.params(arg0: Value).returns(Maybe[T.type_parameter(:NewValue)]))
289
+ .returns(Maybe[T.type_parameter(:NewValue)])
290
+ }
291
+ def flat_map(&blk)
292
+ T.cast(
293
+ self,
294
+ Maybe[T.type_parameter(:NewValue)]
295
+ )
296
+ end
297
+
298
+ sig(:final) {
299
+ override
300
+ .params(blk: T.proc.params(arg0: Value).returns(T::Boolean))
301
+ .returns(Maybe[Value])
302
+ }
303
+ def filter(&blk)
304
+ self
305
+ end
306
+
307
+ sig(:final) { override.returns(T::Boolean) }
308
+ def some?
309
+ false
310
+ end
311
+
312
+ sig(:final) { override.returns(T::Boolean) }
313
+ def none?
314
+ true
315
+ end
316
+
317
+ sig(:final) { override.params(value: Value).returns(Value) }
318
+ def value_or(value)
319
+ value
320
+ end
321
+
322
+ sig(:final) {
323
+ override
324
+ .params(blk: T.proc.params(arg0: Value).void)
325
+ .returns(Maybe[Value])
326
+ }
327
+ def tee(&blk)
328
+ self
329
+ end
330
+
331
+ sig(:final) {
332
+ override
333
+ .type_parameters(:Result)
334
+ .params(fallback: T.type_parameter(:Result), blk: T.proc.params(arg0: Value).returns(T.type_parameter(:Result)))
335
+ .returns(T.type_parameter(:Result))
336
+ }
337
+ def either(fallback, &blk)
338
+ fallback
339
+ end
340
+
341
+ sig(:final) {
342
+ override
343
+ .type_parameters(:Failure)
344
+ .params(failure: T.type_parameter(:Failure))
345
+ .returns(Mayak::Monads::Result[T.type_parameter(:Failure), Value])
346
+ }
347
+ def to_result(failure)
348
+ Mayak::Monads::Result::Failure[T.type_parameter(:Failure), Value].new(failure)
349
+ end
350
+
351
+ sig(:final) { override.params(error: StandardError).returns(Mayak::Monads::Try[Value]) }
352
+ def to_try(error)
353
+ Mayak::Monads::Try::Failure.new(error)
354
+ end
355
+
356
+ sig(:final) { override.params(value: Value).returns(Maybe[Value]) }
357
+ def recover(value)
358
+ Mayak::Monads::Maybe::Some.new(value)
359
+ end
360
+ end
361
+
362
+ module Mixin
363
+ extend T::Sig
364
+
365
+ include Kernel
366
+
367
+ sig {
368
+ type_parameters(:Value)
369
+ .params(value: T.nilable(T.type_parameter(:Value)))
370
+ .returns(Maybe[T.type_parameter(:Value)])
371
+ }
372
+ def Maybe(value)
373
+ case value
374
+ when nil
375
+ Mayak::Monads::Maybe::None[T.type_parameter(:Value)].new
376
+ else
377
+ Mayak::Monads::Maybe::Some[T.type_parameter(:Value)].new(value)
378
+ end
379
+ end
380
+
381
+ sig { returns(Maybe[T.untyped]) }
382
+ def None
383
+ Mayak::Monads::Maybe::None.new
384
+ end
385
+
386
+ sig {
387
+ type_parameters(:Value)
388
+ .params(blk: T.proc.returns(T.type_parameter(:Value)))
389
+ .returns(Maybe[T.type_parameter(:Value)])
390
+ }
391
+ def for_maybe(&blk)
392
+ result = blk.call
393
+ Mayak::Monads::Maybe::Some[T.type_parameter(:Value)].new(result)
394
+ rescue Halt => e
395
+ e.result
396
+ end
397
+
398
+ sig {
399
+ type_parameters(:Value)
400
+ .params(value: Maybe[T.type_parameter(:Value)])
401
+ .returns(T.type_parameter(:Value))
402
+ }
403
+ def do_maybe!(value)
404
+ case value
405
+ when Mayak::Monads::Maybe::Some
406
+ value.value
407
+ when Mayak::Monads::Maybe::None
408
+ raise Halt[T.type_parameter(:Value)].new(value)
409
+ else
410
+ T.absurd(value)
411
+ end
412
+ end
413
+
414
+ sig {
415
+ type_parameters(:Value)
416
+ .params(value: T.type_parameter(:Value), blk: T.proc.returns(T::Boolean))
417
+ .returns(T.type_parameter(:Value))
418
+ }
419
+ def check_maybe!(value, &blk)
420
+ do_maybe!(Mayak::Monads::Maybe.check(value, &blk))
421
+ end
422
+
423
+ sig { params(blk: T.proc.returns(T::Boolean)).void }
424
+ def guard_maybe!(&blk)
425
+ do_maybe!(Mayak::Monads::Maybe.guard(&blk))
426
+ end
427
+
428
+ class Halt < StandardError
429
+ extend T::Sig
430
+ extend T::Generic
431
+ extend T::Helpers
432
+
433
+ SuccessType = type_member
434
+
435
+ sig { returns(Mayak::Monads::Maybe[SuccessType]) }
436
+ attr_reader :result
437
+
438
+ sig { params(result: Mayak::Monads::Maybe[SuccessType]).void }
439
+ def initialize(result)
440
+ super()
441
+
442
+ @result = T.let(result, Mayak::Monads::Maybe[SuccessType])
443
+ end
444
+ end
445
+ private_constant :Halt
446
+ end
447
+ end
448
+ end
449
+ end