Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do notation, monadic guard #12

Closed
wants to merge 4 commits into from

Conversation

Technologicat
Copy link
Contributor

Here's an attempt at do-notation for Python. It seems none of the monad libraries currently provide that.

Example:

from oslash import List, do, let, guard

r = lambda low, high: List.from_iterable(range(low, high))
out = do(let(z=r(1, 21)),               # let is "<-"
         let(x=lambda e: r(1, e.z+1)),  # uses env via "lambda e: ..."
         let(y=lambda e: r(e.x, e.z+1)),
         lambda e: guard(List, e.x*e.x + e.y*e.y == e.z*e.z),
         lambda e: List.unit((e.x, e.y, e.z)))
print(out)

The syntax is loosely modeled after letrec in unpythonic, which in turn was inspired by [1] [2] [3].

This is pure Python 3.4, implemented essentially as a code generator. The client code would look cleaner if this was a syntactic macro instead (using MacroPy3), but this version makes do (no pun intended) with Python's builtin capabilities.

Comments welcome.

Also, I think guard is useful, especially with List. Where should it go in OSlash?

@Technologicat
Copy link
Contributor Author

FWIW, since posting this, I've added a MacroPy3-based do-notation to unpythonic. Since unpythonic is not really a monad library, it's currently hard-coded for the List monad (but this limitation is easily removed).

See the forall syntax transformer in forall.py. It's much cleaner and much less hacky than what is possible without macros.

(For comparison, the same feature is implemented without macros in the badly named amb.py, but the code in this PR already contains a clean minimal version of the relevant parts of that.)

If you're interested in the macro approach, it could be adapted here.

@sobolevn
Copy link
Contributor

sobolevn commented Jul 5, 2020

@Technologicat you might be interested in this issue: dry-python/returns#392

We are working on typed do-notation in Python, and I would love to hear your ideas about it!

@dbrattli
Copy link
Owner

This is pure gold! Sorry for taking so long. Been lost in F# for a long time. Planning to merge this soon.

@dbrattli
Copy link
Owner

I'm closing this as the commits here have now been merged into master through #19 since I didn't have write access to the PR. Again, thanks for your contribution to OSlash!

@dbrattli dbrattli closed this Sep 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants