3.2.2. effect.do module

An imperative-looking notation for Effectful code.

See do().

effect.do.do(f)

A decorator which allows you to use do notation in your functions, for imperative-looking code:

@do
def foo():
    thing = yield Effect(Constant(1))
    yield do_return('the result was %r' % (thing,))

eff = foo()
return eff.on(...)

@do must decorate a generator function (not any other type of iterator). Any yielded values must either be Effects or the result of a do_return() call. The result of a yielded Effect will be passed back into the generator as the result of the yield expression. Yielded do_return() values will provide the ultimate result of the Effect that is returned by the decorated function. Note that do_return() is only necessary for Python 2 compatibility; return statements can be used directly in Python 3-only code.

It’s important to note that any generator function decorated by @do will no longer return a generator, but instead it will return an Effect, which must be used just like any other Effect.

Errors are also converted to normal exceptions:

@do
def foo():
    try:
        thing = yield Effect(Error(RuntimeError('foo')))
    except RuntimeError:
        yield do_return('got a RuntimeError as expected')

(This decorator is named for Haskell’s do notation, which is similar in spirit).

effect.do.do_return(val)

Specify a return value for a @do function.

The result of this function must be yielded. e.g.:

@do
def foo():
    yield do_return('hello')

If you’re writing Python 3-only code, you don’t need to use this function, and can just use the return statement as normal.