pymonad.promise | index /usr/home/jason/Files/projects/pymonad/pymonad/promise.py |
Implements the Promise monad for ordering concurrent computations.
The Promise monad is based on (and named after) Javascript's Promise
objects and function in a similar way. Promises take asynchronous
computations and ensure the ordering of execution. In addition to the
standard operations on monads, Promises also provide a 'catch' method
which allows for recovery from errors.
Example:
import asyncio
from pymonad.promise import Promise
from pymonad.tools import curry
@curry(2)
def div(y, x):
return x / y
async def long_id(x):
await asyncio.sleep(1)
return await Promise(lambda resolve, reject: resolve(x))
async def main():
x = (Promise.insert(1)
.then(long_id))
y = (Promise
.insert(2)
.then(long_id)
.then(div(0)) # Raises an error...
.catch(lambda error: 2)) # ...which is dealth with here.
print(
await Promise.apply(add)
.to_arguments(x, y)
.catch(lambda error: 'Recovering...') # This is ignored
# because the previous
# catch already dealt
# with the error.
)
asyncio.run(main())
The above example will print the value '3' to the screen. The
'long_id' coroutine is a stand-in for any async operation that may
take some amount of time. When we await the Promise inside the print()
call it waits for both arguments to complete before calling 'add' with
the results. If the first call to 'catch' were removed then the error
would propagate and be caught by the second call. The program would
then print the string 'Recovering...' instead of '3'.
You can also create a Promise by passing a function directly. This
function takes two callbacks as input to signal a successful
computation or a failed one.
Example:
import asyncio
def main():
print(await Promise(lambda resolve, reject: resolve(2)))
asyncio.run(main())
The 'resolve' callback can take a value of any type but the 'reject'
callback should always take an Exception as its argument.
Example:
import asyncio
def main():
print(await Promise(lambda resolve, reject: reject(IndexError())))
asyncio.run(main())
When run, this program will crash having raised the IndexError without
catching it. Similarly, the catch method takes a function which
accepts an Exception as it's input.
Example:
import asyncio
def main():
print(await Promise(lambda resolve, reject: reject(IndexError()))
.catch(lambda error: print(type(error)))
)
asyncio.run(main())
This program prints "<type 'IndexError'>" as its output.
Modules | ||||||
|
Functions | ||
|
Data | ||
Callable = typing.Callable PromiseFunction = typing.Callable[[typing.Callable[[~S], ~T], typing.Callable[[Exception], ~T]], ~T] RejectFunction = typing.Callable[[Exception], ~T] ResolveFunction = typing.Callable[[~S], ~T] S = ~S T = ~T Union = typing.Union |