-
-
Notifications
You must be signed in to change notification settings - Fork 123
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
Think about typed do-notation #392
Comments
FWIW... Parsy (parser combinator library) has a way of mimicking their example: @generate("form")
def form():
yield lparen
exprs = yield expr.many()
yield rparen
return exprs if roughly equivalent to: form = do
lparen
exprs <- expr.many()
rparen
exprs ...where the correspondence works well enough, in this specific domain, that I was able to translate a bunch of code from Haskell's Megaparsec library into Python in a fairly straightforward way usefully the generator/ I don't know how similar or different this is to what you tried already, or if it's not useful, but if it's helpful at all then I'm glad 😄 |
@anentropic I have tried this approach. It works fine. But, it is impossible to type it properly. Because, generators require to use When this parameter is specified, it becomes impossible to use other types inside your do-notation. |
Currently I am thinking about this API: assert do(
x + y
for x in wrap(Some(1))
for y in wrap(Success(2))
) == 3 But, this API still does not work properly with Ideas?! 💯 |
@papaver since I feel very inspired by your implementation I would love to hear your opinion and ideas about it! 🙂 Related: https://github.com/papaver/pyfnz/blob/master/pyfnz/either.py |
I am curious, I didn't fully understand the typing issue with generators+yield expressions.... and this looks like a generator expression as an argument to a function. Does it not have the same problem?
(none of this is intended as a criticism, I am just curious about the issues involved) |
@anentropic maybe I got your idea wrong. Can you please send a simple working demo? |
Related: dbrattli/OSlash#12 |
@sobolevn i ended up going the generator route as it resulted in the cleanest code while still looking like python. all the other implementations i ran into were fairly gross looking and convoluted to force the code to do something it wasn't meant for (like the decorator with dozens of yields). the for comprehension was was able to do a form of 'lifting' for free, cleanly. i actually use that pattern in code all the time now. most people just don't understand the power of the for comprehension.
personally i think typed python is a step backwards so i haven't messed with it. python is extremely powerful functionally without types. |
We can also try to use something similar to Like so: with (
result as success_value,
needs_raw(success_value) as returns_raw,
):
print(returns_raw) |
This is maybe obvious and the reason you chose it, but I like
which is also consistent with how Resource is used in scala cats and other monadic behavior. I'm not crazy about the needs_raw notation though and it would make sense to stick with
|
@sobolevn any other thoughts about this? Is anyone working on this yet? |
Nope, this issue is not in the works right now. I like the generator expression approach: do(
x + y + z
for x in c(Some(1))
for y in c(Some(2))
for z in c(Some(3))
) With the support of async generators for Do you want to work on it? |
A couple of thoughts here:
|
Illustration in Haskell: ( do
x <- note "maybeX was Nothing!" (Just 1)
y <- Right 2
return (x + y) ) == Right 3 |
I have removed
@pipeline
in0.14
release.It had lots of problems:
Failure
types: We have a problem with @pipeline and unwrap() #90IOResult
andFutureResult
Maybe
andResult
in the same@pipeline
I would love to have some solution instead! But, no ideas about how it should work or look like. So, any ideas are welcome.
The text was updated successfully, but these errors were encountered: