@@ -42,7 +42,53 @@ class RequiresContextFutureResult(
42
42
BaseContainer ,
43
43
Generic [_EnvType , _ValueType , _ErrorType ],
44
44
):
45
- """Someday this container will grow very big."""
45
+ """
46
+ The ``RequiresContextFutureResult`` combinator.
47
+
48
+ This probably the main type people are going to use in ``async`` programms.
49
+
50
+ See :class:`returns.context.requires_context.RequiresContext`,
51
+ :class:`returns.context.requires_context_result.RequiresContextResult`,
52
+ and
53
+ :class:`returns.context.requires_context_result.RequiresContextIOResult`
54
+ for more docs.
55
+
56
+ This is just a handy wrapper around
57
+ ``RequiresContext[env, FutureResult[a, b]]``
58
+ which represents a context-dependent impure operation that might fail.
59
+
60
+ So, this is a thin wrapper, without any changes in logic.
61
+ Why do we need this wrapper? That's just for better usability!
62
+
63
+ This way ``RequiresContextIOResult`` allows to simply work with:
64
+
65
+ - raw values and pure functions
66
+ - ``RequiresContext`` values and pure functions returning it
67
+ - ``RequiresContextResult`` values and pure functions returning it
68
+ - ``RequiresContextIOResult`` values and pure functions returning it
69
+ - ``Result`` and pure functions returning it
70
+ - ``IOResult`` and functions returning it
71
+ - ``FutureResult`` and functions returning it
72
+ - other ``RequiresContextFutureResult`` related functions and values
73
+
74
+ This is a complex type for complex tasks!
75
+
76
+ Important implementation detail:
77
+ due it is meaning, ``RequiresContextFutureResult``
78
+ cannot have ``Success`` and ``Failure`` subclasses.
79
+
80
+ We only have just one type. That's by design.
81
+
82
+ Different converters are also not supported for this type.
83
+ Use converters inside the ``RequiresContext`` context, not outside.
84
+
85
+ See also:
86
+ https://dev.to/gcanti/getting-started-with-fp-ts-reader-1ie5
87
+ https://en.wikipedia.org/wiki/Lazy_evaluation
88
+ https://bit.ly/2R8l4WK
89
+ https://bit.ly/2RwP4fp
90
+
91
+ """
46
92
47
93
#: Inner value of `RequiresContext`
48
94
#: is just a function that returns `FutureResult`.
@@ -188,15 +234,7 @@ def bind(
188
234
>>> from returns.future import FutureResult
189
235
>>> from returns.io import IOSuccess, IOFailure
190
236
191
- >>> def first(lg: bool) -> RequiresContextFutureResult[int, int, int]:
192
- ... # `deps` has `int` type here:
193
- ... return RequiresContextFutureResult(
194
- ... lambda deps: FutureResult.from_value(
195
- ... deps,
196
- ... ) if lg else FutureResult.from_failure(-deps),
197
- ... )
198
-
199
- >>> def second(
237
+ >>> def function(
200
238
... number: int,
201
239
... ) -> RequiresContextFutureResult[int, str, int]:
202
240
... # `deps` has `int` type here:
@@ -205,11 +243,13 @@ def bind(
205
243
... )
206
244
207
245
>>> assert anyio.run(
208
- ... first(True).bind(second)(1).awaitable,
209
- ... ) == IOSuccess('2')
246
+ ... RequiresContextFutureResult.from_value(2).bind(function),
247
+ ... 3,
248
+ ... ) == IOSuccess('5')
210
249
>>> assert anyio.run(
211
- ... first(False).bind(second)(2).awaitable,
212
- ... ) == IOFailure(-2)
250
+ ... RequiresContextFutureResult.from_failure(2).bind(function),
251
+ ... 3,
252
+ ... ) == IOFailure(2)
213
253
214
254
"""
215
255
return RequiresContextFutureResult (
@@ -229,11 +269,11 @@ def bind_result(
229
269
230
270
>>> import anyio
231
271
>>> from returns.context import RequiresContextFutureResult
232
- >>> from returns.result import Success, Failure, Result
272
+ >>> from returns.result import Success, Result
233
273
>>> from returns.io import IOSuccess, IOFailure
234
274
235
275
>>> def function(num: int) -> Result[int, str]:
236
- ... return Success(num + 1) if num > 0 else Failure('<0')
276
+ ... return Success(num + 1)
237
277
238
278
>>> assert anyio.run(
239
279
... RequiresContextFutureResult.from_value(1).bind_result(
@@ -242,13 +282,6 @@ def bind_result(
242
282
... RequiresContextFutureResult.empty,
243
283
... ) == IOSuccess(2)
244
284
245
- >>> assert anyio.run(
246
- ... RequiresContextFutureResult.from_value(0).bind_result(
247
- ... function,
248
- ... ),
249
- ... RequiresContextFutureResult.empty,
250
- ... ) == IOFailure('<0')
251
-
252
285
>>> assert anyio.run(
253
286
... RequiresContextFutureResult.from_failure(':(').bind_result(
254
287
... function,
@@ -280,8 +313,6 @@ def bind_context(
280
313
>>> def function(arg: int) -> RequiresContext[str, int]:
281
314
... return RequiresContext(lambda deps: len(deps) + arg)
282
315
283
- >>> assert function(2)('abc') == 5
284
-
285
316
>>> assert anyio.run(
286
317
... RequiresContextFutureResult.from_value(2).bind_context(
287
318
... function,
@@ -318,34 +349,20 @@ def bind_context_result(
318
349
>>> import anyio
319
350
>>> from returns.context import RequiresContextResult
320
351
>>> from returns.io import IOSuccess, IOFailure
321
- >>> from returns.result import Success, Failure
352
+ >>> from returns.result import Success
322
353
323
354
>>> def function(arg: int) -> RequiresContextResult[str, int, int]:
324
- ... if arg > 0:
325
- ... return RequiresContextResult(
326
- ... lambda deps: Success(len(deps) + arg),
327
- ... )
328
355
... return RequiresContextResult(
329
- ... lambda deps: Failure (len(deps) + arg),
356
+ ... lambda deps: Success (len(deps) + arg),
330
357
... )
331
358
332
- >>> assert function(2)('abc') == Success(5)
333
- >>> assert function(-1)('abc') == Failure(2)
334
-
335
359
>>> instance = RequiresContextFutureResult.from_value(
336
360
... 2,
337
361
... ).bind_context_result(
338
362
... function,
339
363
... )('abc')
340
364
>>> assert anyio.run(instance.awaitable) == IOSuccess(5)
341
365
342
- >>> instance = RequiresContextFutureResult.from_value(
343
- ... -1,
344
- ... ).bind_context_result(
345
- ... function,
346
- ... )('abc')
347
- >>> assert anyio.run(instance.awaitable) == IOFailure(2)
348
-
349
366
>>> instance = RequiresContextFutureResult.from_failure(
350
367
... 2,
351
368
... ).bind_context_result(
@@ -405,7 +422,7 @@ def bind_ioresult(
405
422
>>> from returns.io import IOResult, IOSuccess, IOFailure
406
423
407
424
>>> def function(num: int) -> IOResult[int, str]:
408
- ... return IOSuccess(num + 1) if num > 0 else IOFailure('<0')
425
+ ... return IOSuccess(num + 1)
409
426
410
427
>>> assert anyio.run(
411
428
... RequiresContextFutureResult.from_value(1).bind_ioresult(
@@ -414,13 +431,6 @@ def bind_ioresult(
414
431
... RequiresContextFutureResult.empty,
415
432
... ) == IOSuccess(2)
416
433
417
- >>> assert anyio.run(
418
- ... RequiresContextFutureResult.from_value(0).bind_ioresult(
419
- ... function,
420
- ... ),
421
- ... RequiresContextFutureResult.empty,
422
- ... ) == IOFailure('<0')
423
-
424
434
>>> assert anyio.run(
425
435
... RequiresContextFutureResult.from_failure(':(').bind_ioresult(
426
436
... function,
@@ -510,16 +520,14 @@ def rescue(
510
520
>>> import anyio
511
521
>>> from returns.context import RequiresContextFutureResult
512
522
>>> from returns.future import FutureResult
513
- >>> from returns.io import IOSuccess, IOFailure
523
+ >>> from returns.io import IOSuccess
514
524
515
525
>>> def rescuable(
516
526
... arg: str,
517
527
... ) -> RequiresContextFutureResult[str, str, str]:
518
528
... return RequiresContextFutureResult(
519
529
... lambda deps: FutureResult.from_value(
520
530
... deps + arg,
521
- ... ) if len(arg) > 1 else FutureResult.from_failure(
522
- ... arg + deps,
523
531
... ),
524
532
... )
525
533
@@ -528,13 +536,6 @@ def rescue(
528
536
... 'c',
529
537
... ) == IOSuccess('a')
530
538
531
- >>> assert anyio.run(
532
- ... RequiresContextFutureResult.from_failure('a').rescue(
533
- ... rescuable,
534
- ... ),
535
- ... 'c',
536
- ... ) == IOFailure('ac')
537
-
538
539
>>> assert anyio.run(
539
540
... RequiresContextFutureResult.from_failure('aa').rescue(
540
541
... rescuable,
0 commit comments