Skip to content

Latest commit

 

History

History
37 lines (28 loc) · 1.29 KB

README.md

File metadata and controls

37 lines (28 loc) · 1.29 KB

python_do_notation

A reckless implementation of monadic do notation in python, to see if I can.

In do_notation.py, defines a decorator with_do_notation that rewrites statements like

with do(Maybe) as y:
        a = Maybe(just=x) if x > 0 else Maybe()
        b = Maybe(just=x*a)
        mreturn(a+b)

into

y = (Maybe(just=x) if x > 0 else Maybe()).bind(lambda a:
     Maybe(just=x*a)                     .bind(lambda b:
     Maybe.mreturn(a+b)))

Usage examples: In a maybe_examply.py, list_example.py, and parser_example.py defines the Maybe monad, a List monad, and a monadic parser, showing usage in each.

Just use it like any other decorator, and you can use this magical new syntax. All it does is rewrite newlines and assignments into a chain of binds, and changes mreturn into the specific mreturn needed for the monad in use within that do block.

@with_do_notation
def decrement_positives(x):
    with do(Maybe) as y:
        a = Maybe(just=x) if x > 0 else Maybe()
        mreturn(a-1)
    return y

It's great as long as you don't care much about poor performance, occasional exceptions coming from the lack of tail call optimization in python, and what amounts to a mystery step in your tracebacks:

mystery step