@@ -461,6 +461,78 @@ def fn5() -> Generator[int, int, int]:
461461pinned to `Exception` i.e., `Result[TSource, Exception]`.
462462"""
463463
464+ # %% [markdown]
465+ """
466+ ### AsyncResult
467+
468+ The `AsyncResult[T, TError]` type is the asynchronous version of `Result`. It allows you
469+ to compose asynchronous operations that may fail, using the Result type. This is
470+ particularly useful for handling errors in asynchronous code, such as API calls,
471+ database operations, or any other I/O-bound tasks.
472+
473+ Similar to the `Result` effect, AsyncResult enables "railway oriented programming" but
474+ for asynchronous operations. If any part of the function yields an `Error`, the function
475+ is short-circuited and the following statements will never be executed.
476+ """
477+
478+ # %%
479+ from collections .abc import AsyncGenerator
480+
481+ from expression import Error , Ok , effect
482+
483+
484+ @effect .async_result [int , str ]()
485+ async def fn () -> AsyncGenerator [int , int ]:
486+ x : int = yield 42 # Regular value
487+ y : int = yield await Ok (43 ) # Awaitable Ok value
488+
489+ # Short-circuit if condition is met
490+ if x + y > 80 :
491+ z : int = yield await Error ("Value too large" ) # This will short-circuit
492+ else :
493+ z : int = yield 44
494+
495+ yield x + y + z # Final value
496+
497+
498+ # This would be run in an async context
499+ # result = await fn()
500+ # assert result == Error("Value too large")
501+
502+ # %% [markdown]
503+ """
504+ AsyncResult works well with other async functions and can be nested:
505+ """
506+
507+
508+ # %%
509+ @effect .async_result [int , str ]()
510+ async def inner (x : int ) -> AsyncGenerator [int , int ]:
511+ y : int = yield x + 1
512+ yield y + 1 # Final value is y + 1
513+
514+
515+ @effect .async_result [int , str ]()
516+ async def outer () -> AsyncGenerator [int , int ]:
517+ x : int = yield 40
518+
519+ # Call inner and await its result
520+ inner_result = await inner (x )
521+ y : int = yield await inner_result
522+
523+ yield y # Final value is y
524+
525+
526+ # This would be run in an async context
527+ # result = await outer()
528+ # assert result == Ok(42) # 40 -> 41 -> 42
529+
530+ # %% [markdown]
531+ """
532+ A simplified type called `AsyncTry` is also available. It's an async result type that is
533+ pinned to `Exception` i.e., `AsyncResult[TSource, Exception]`.
534+ """
535+
464536# %% [markdown]
465537"""
466538### Sequence
0 commit comments