Skip to content

Instantly share code, notes, and snippets.

@pstiasny
Created January 22, 2018 04:35
Show Gist options
  • Save pstiasny/79fecc7275c7c2383db0e6443cc17dc0 to your computer and use it in GitHub Desktop.
Save pstiasny/79fecc7275c7c2383db0e6443cc17dc0 to your computer and use it in GitHub Desktop.
IO monad recreated in Python
class IO(object):
@classmethod
def ret(cls, x):
return IOReturn(x)
def bind(self, f):
return IOBind(self, f)
class IOBind(IO):
def __init__(self, bindm, bindf):
self.bindm = bindm
self.bindf = bindf
class IOReturn(IO):
def __init__(self, x):
self.x = x
class IOPrint(IO):
def __init__(self, str_):
self.op = 'print'
self.str = str_
class IORead(IO):
def __init__(self):
self.op = 'read'
ioprint = lambda str_: IOPrint(str_)
ioread = lambda: IORead()
def runIO(io):
if hasattr(io, 'bindm') and hasattr(io, 'bindf'):
x = runIO(io.bindm)
return runIO(io.bindf(x))
if hasattr(io, 'x'):
return io.x
if getattr(io, 'op') == 'print':
print io.str
return ()
if getattr(io, 'op') == 'read':
return raw_input()
#
# Example program
#
import re
getname = (lambda:
ioprint('what is your name?').bind(lambda _:
ioread().bind(lambda name:
IO.ret(name) if re.match('^[A-Z][a-z]+$', name) else
getname()
)))
main = (lambda:
getname().bind(lambda name:
ioprint('Hello, ' + name)
))
runIO(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment