Skip to content

Instantly share code, notes, and snippets.

@ericmoritz
Last active December 21, 2015 11:59
Show Gist options
  • Select an option

  • Save ericmoritz/6302538 to your computer and use it in GitHub Desktop.

Select an option

Save ericmoritz/6302538 to your computer and use it in GitHub Desktop.
from functools import partial
class Monad(object):
@classmethod
def liftM(cls, f):
def arrow(x):
return cls.ret(f(x))
def lifted(m):
return cls.bind(m, arrow)
return lifted
@classmethod
def kcompose(cls, f, g):
return lambda x: cls.bind(
f(x),
g
)
class Maybe(Monad):
"""
Implements a Maybe monad that operates on values that
that are either something or None.
"""
@classmethod
def ret(cls, v):
return v
@classmethod
def bind(cls, v, f):
if v is not None:
return f(v)
def compose(g, f):
def composed(*args, **kwargs):
return f(g(*args, **kwargs))
return composed
def lookup(key, d):
"""
lookup(key, dict) -> any | None
Returns a value or None, i.e. a Pythonic Maybe.
"""
return d.get(key)
# A collection of data
data = {
"people": {
"eric": {"name": "Eric", "age": 33},
"gina": {"name": "Gina"}
},
}
# Lets lookup age and multiply by 2
def times2(x):
return x * 2
def multiply_age_by_two(person, data):
return compose(
Maybe.kcompose(
Maybe.kcompose(
partial(lookup, "people"),
partial(lookup, person)),
partial(lookup, "age")),
Maybe.liftM(lambda x: x * 2))(data)
def multiply_age_by_two2(person, data):
"""
The K.I.S.S. approach...
"""
try:
return data['people'][person]['age'] * 2
except KeyError:
return None
print multiply_age_by_two("eric", data)
print multiply_age_by_two("gina", data)
@ericmoritz
Copy link
Author

ugg, that's nasty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment