Created
September 18, 2019 10:02
-
-
Save bedekelly/decd5c6da32471a8a99d34aa8279b78c to your computer and use it in GitHub Desktop.
Do Notation using Python's Yield Keyword
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
def do(f): | |
def partial_run(f, args, kwargs, values_so_far=()): | |
# First, create a NEW instance of the coroutine. | |
coroutine = f(*args, **kwargs) | |
# Advance the coroutine to the first yield point. | |
yielded_monad = next(coroutine) | |
# For each value so far, send it into the coroutine. | |
for v in values_so_far: | |
try: | |
yielded_monad = coroutine.send(v) | |
except StopIteration as ret: | |
# This means we've reached the end of the function; | |
# lift the return value back into the monad. | |
return yielded_monad.point(ret.value) | |
def continue_with_value(value): | |
"""Continue the coroutine execution, pre-filling a given value.""" | |
return partial_run(f, args, kwargs, (*values_so_far, value)) | |
return yielded_monad >> continue_with_value | |
@wraps | |
def wrapped(*args, **kwargs): | |
return partial_run(f, args, kwargs) | |
return wrapped |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment