Future — lazy async computation.
Future[A] wraps Awaitable[A]. A generic async monad — no error semantics built in.
For error handling, use AsyncResult[A] from funstruct.monad.result.
Future
Bases: DataType, Generic[A]
Lazy async computation that produces A when awaited.
Source code in funstruct/monad/future/__init__.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 | class Future(DataType, Generic[A]):
"""Lazy async computation that produces A when awaited."""
def __init__(self, coro: Awaitable[A]) -> None:
self._coro = ReAwaitable(coro) if not isinstance(coro, ReAwaitable) else coro
def __del__(self):
pass
def __await__(self) -> Generator[None, None, A]:
return self._awaitable().__await__()
async def _awaitable(self) -> A:
return await self._coro
def bind(self, f: Callable[[A], Future[B]]) -> Future[B]:
async def _inner():
result = await self._coro
return await f(result)
return Future(_inner())
@classmethod
def do(cls, gen_fn: Callable) -> Callable[..., Future]:
"""Do-notation for Future.
>>> @Future.do
... def pipeline():
... x = yield Future.pure(1)
... y = yield Future.pure(x + 10)
... return x + y
"""
def _thunk(*args, **kwargs):
async def _run():
gen = gen_fn(*args, **kwargs)
try:
monadic_val = next(gen)
while True:
value = await monadic_val
monadic_val = gen.send(value)
except StopIteration as e:
return e.value
return cls(_run())
return _thunk
@classmethod
def pure(cls, value: A) -> Future[A]:
async def _inner():
return value
return cls(_inner())
def __repr__(self) -> str:
return f"Future({self._coro})"
|
do(gen_fn)
classmethod
Do-notation for Future.
@Future.do
... def pipeline():
... x = yield Future.pure(1)
... y = yield Future.pure(x + 10)
... return x + y
Source code in funstruct/monad/future/__init__.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 | @classmethod
def do(cls, gen_fn: Callable) -> Callable[..., Future]:
"""Do-notation for Future.
>>> @Future.do
... def pipeline():
... x = yield Future.pure(1)
... y = yield Future.pure(x + 10)
... return x + y
"""
def _thunk(*args, **kwargs):
async def _run():
gen = gen_fn(*args, **kwargs)
try:
monadic_val = next(gen)
while True:
value = await monadic_val
monadic_val = gen.send(value)
except StopIteration as e:
return e.value
return cls(_run())
return _thunk
|