lisa.monad#
Monads with syntactic sugar.
All monads share the following API:
# for a given monad Monad
# Turns a regular function into a function returning an instance of Monad,
# and able to await on monadic values. Similar to the "do notation" in
# Haskell.
@Monad.do
async def foo(x, y):
# Inside a decorated function, await can be used to "extract" the value
# contained in the monad, like ``<-`` in Haskell.
z = await Monad.something()
return x
# Equivalent to
@Monad.do
async def foo(x, y):
# note: await is used automatically if x is an instance of Monad
x_ = await x
y_ = await y
# Monad.pure() is called if x_ is not an instance of Monad
return Monad.pure(x_)
This allow composing decorated functions easily
Note
There currently is no overridable bind
operation, since nothing
in Python currently allows getting a proper continuation without explicit
manipulations of lambdas. The closest thing that is used is coroutine
functions, where await
somewhat provides a continuation using
coroutine.send()
. The limitation comes from that it can only be called
at most once (preventing anything like the list monad). Early-return
control flow such as the maybe monad are typically not necessary as Python
has exceptions already.
Note
async/await
is used as syntactic sugar instead of yield
since
the grammar works better for await
. yield
cannot be used in
comprehensions, which prevents some idiomatic functional patterns based on
generator expressions.
Globals
Classes
Monad transformer allowing the decorated coroutine function to await on non-monadic values. This is useful to mix any monad transformer defined in this module with other async APIs, such as |
|
Specialization of |
|
Abstract Base Class parametrized by a type T, like a container of some sort. |
|
Base class for monad transformers. |
|
Wraps an arbitrary value to indicate its presence. |
|
Monad transformer analogous to Haskell’s |
|
Same as |
Functions
Allows stacking together multiple |
Exceptions
Exception raised by |