Skip to content

Instantly share code, notes, and snippets.

@apg
Created April 12, 2011 18:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apg/916132 to your computer and use it in GitHub Desktop.
Save apg/916132 to your computer and use it in GitHub Desktop.
"""Monads in Python, as close as I can get them to
Haskell
"""
class Monad(object):
def return_(self, value):
raise NotImplementedError()
def __ge__(self, mf):
raise NotImplementedError()
class Maybe(Monad):
def __init__(self):
super(Monad, self).__init__()
@classmethod
def return_(cls, value):
return Just(value)
class Just(Maybe):
def __init__(self, value):
super(Maybe, self).__init__()
self._value = value
def __ge__(self, mf):
return mf(self._value)
def __repr__(self):
return 'Just(%s)' % (repr(self._value))
__str__ = __repr__
class _Nothing(Maybe):
def __ge__(self, mf):
return self
def __repr__(self):
return 'Nothing'
__str__ = __repr__
Nothing = _Nothing()
if __name__ == '__main__':
# 1.
# print Just(5) >= lambda x: Just(x + 5)) >= lambda x: Maybe.return_(x)
# File "monad.py", line 49
# print Just(5) >= lambda x: Just(x + 5)) >= lambda x: Maybe.return_(x)
# ^
# SyntaxError: invalid syntax
# 2.
print Just(5) >= (lambda x: Just(x + 5)) >= (lambda x: Maybe.return_(x))
# False --- ????
# 3.
print (Just(5) >= (lambda x: Just(x + 5))) >= (lambda x: Maybe.return_(x))
# Just(10) --- Now we're on to something, but WTF?
# 4.
print (Nothing >= (lambda x: Just(x + 5))) >= (lambda x: Maybe.return_(x))
# Nothing -- again, as expected, but with crazy loads of parens...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment