Skip to content

Instantly share code, notes, and snippets.

@tomerfiliba
Created January 12, 2012 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomerfiliba/1602979 to your computer and use it in GitHub Desktop.
Save tomerfiliba/1602979 to your computer and use it in GitHub Desktop.
from utils import singleton
from monads import monadic, MonadRunner
class Text(object):
def __init__(self, text):
self.text = text
class Input(object):
def __init__(self, label):
self.label = label
@singleton
class TerminalDialogRunner(MonadRunner):
def bind_Text(self, obj):
print obj.text
def bind_Input(self, obj):
print obj.label
return raw_input()
@monadic
def bar(name):
yield Text("so %s, i hope you like this" % (name,))
yield Text("cuz this is some impressive shit")
@monadic
def foo():
yield Text("hi man")
name = yield Input("what's your name?")
yield bar(name)
yield Text("okay, m'bye")
TerminalDialogRunner.run(foo())
import functools
class MonadReturn(Exception):
def __init__(self, value):
self.value = value
class UnknownMonadicAction(Exception):
pass
class Monad(object):
def __init__(self, gen):
self.gen = gen
def run(self, bind):
inp = None
ret = None
while True:
try:
out = self.gen.send(inp)
except StopIteration:
break
except MonadReturn as ex:
ret = ex.value
break
inp = bind(out)
return ret
def monadic(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return Monad(func(*args, **kwargs))
return wrapper
class MonadRunner(object):
def bind(self, obj):
return getattr(self, "bind_%s" % (type(obj).__name__,), self.unknown)(obj)
def bind_Monad(self, mnd):
return mnd.run(self.bind)
run = bind_Monad
def unknown(self, obj):
raise UnknownMonadicAction(obj)
def mreturn(value):
raise MonadReturn(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment