Skip to content

Instantly share code, notes, and snippets.

@esehara
Created December 10, 2011 16:10
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 esehara/1455469 to your computer and use it in GitHub Desktop.
Save esehara/1455469 to your computer and use it in GitHub Desktop.
PyMonad (Draft Maybe)
import types
class NotFunctionException(Exception):
def __init__(self,value):
self.value = value
def __str__(self):
return repr("NotFunctionException")
class NotMonadException(Exception):
def __init__(self,value):
self.value = value
def __str__(self):
return repr("NotMonadException:" + self.value)
class Maybe:
def bind(self,f,arg):
## -- Type Check
if not isMonad(arg):raise NotMonadException(arg)
if ( (type(f) is not types.FunctionType)
and (type(f) is types.InstanceType)
and (type(f) is not types.MethodType)):
raise NotFunctionException(f)
MonadType,MonadValue = arg
## If Nothing, return Nothing
if MonadType == "Nothing":
return ("Nothing",None)
elif MonadType == "Just":
return f(MonadValue)
else:
raise NotMonadException(arg)
def just(self,arg):
return ("Just",arg)
def fail(self,arg):
return ("Nothing",None)
def isMonad(arg):
if not isinstance(arg,tuple):return False
if not isinstance(arg[0],str):return False
return True
def MonadLawTest():
MonadTest = lambda x:("Just",x + 1)
MonadTest2 = lambda x:("Just",x * 2)
maybe = Maybe()
print """
1.(return x) >>= f == f x
Rewrite:Python
maybe.bind(f,maybe.just(x)) == f(x)
Test ::
"""
print maybe.bind(MonadTest,maybe.just(5)) == MonadTest(5)
print """
2. m >>= return == m
Rewrite:Python
maybe.bind(maybe.just,m) == m
Test ::
"""
print maybe.bind(maybe.just,("Just",5)) == ("Just",5)
print """
3. (m >>= f ) >>= g == m >>= (\\x -> f x >>= g)
Rewrite.Python
(\\x -> f x >>= g) --> (lambda x:("Just",maybe.bind(g,f(x))))
m >>= \\x .. --> maybe.bind(\\x,m)
----> maybe.bind((lambda x:maybe.bind(g,f(x))),m)
maybe.bind(g,maybe.bind(f,m)) == maybe.bind((lambda x:maybe.bind(g,f(x))),m)
Test::
"""
test = maybe.bind(MonadTest2,maybe.bind(MonadTest,("Just",5)))
test2 = maybe.bind((lambda x:maybe.bind(MonadTest2,MonadTest(x))),("Just",5))
print test == test2
if __name__ == "__main__":MonadLawTest()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment