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

Nothing

Similar to Some but indicating the absence of value.

Classes

Async

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 asyncio.

AsyncIO

Specialization of lisa.monad.Async to asyncio event loop.

Monad

Abstract Base Class parametrized by a type T, like a container of some sort.

MonadTrans

Base class for monad transformers.

Option

Monad transformer that manipulates Some and Nothing.

Some

Wraps an arbitrary value to indicate its presence.

State

Monad transformer analogous to Haskell’s StateT transformer.

StateDiscard

Same as State except that calling monadic values will return the computed value instead of a tuple (value, state).

Functions

TransformerStack()

Allows stacking together multiple MonadTrans, e.g.::.

Exceptions

AlreadyCalledError

Exception raised by _CallOnce when the wrapped function has already been called once.