Skip to content

Instantly share code, notes, and snippets.

@mx-moth
Last active June 28, 2017 07:32
Show Gist options
  • Save mx-moth/8cf1b6ce0d6d9b201913a4f0519b976e to your computer and use it in GitHub Desktop.
Save mx-moth/8cf1b6ce0d6d9b201913a4f0519b976e to your computer and use it in GitHub Desktop.
Automatic partially-applied binary operators ala Haskell, for Python
class Comparator():
"""Support 'partial binding' of built in operators."""
def __call__(self, a):
"""For support of nested PendingOperations, comparator(a) == a"""
return a
# A bunch of boring operators
def __lt__(self, b):
return PendingOperation(lambda a: self(a) < b)
def __gt__(self, b):
return PendingOperation(lambda a: self(a) > b)
def __eq__(self, b):
return PendingOperation(lambda a: self(a) == b)
def __mod__(self, b):
return PendingOperation(lambda a: self(a) % b)
def __and__(self, b):
return PendingOperation(lambda a: self(a) & b)
def __or__(self, b):
return PendingOperation(lambda a: self(a) | b)
def __add__(self, b):
return PendingOperation(lambda a: self(a) + b)
def __sub__(self, b):
return PendingOperation(lambda a: self(a) - b)
def __mult__(self, b):
return PendingOperation(lambda a: self(a) * b)
def __truediv__(self, b):
return PendingOperation(lambda a: self(a) / b)
def __floordiv__(self, b):
return PendingOperation(lambda a: self(a) // b)
def __getitem__(self, key):
return PendingOperation(lambda a: self(a)[key])
def __getattr__(self, attr):
return PendingOperation(lambda a: getattr(self(a), attr))
class PendingOperation(Comparator):
"""Support for chainable partially bound functions"""
def __init__(self, fn):
self.fn = fn
def __call__(self, value):
value = self.fn(value)
return value
# Various aliases for a comparator instance. Pick one you like
_ = x = thing = item = Comparator()
def test():
"""Put the comparator through its paces"""
assert (thing < 10)(5)
assert (thing > 10)(15)
assert list(filter(_ < 5, range(10))) == [0, 1, 2, 3, 4]
assert list(filter(x % 2 == 0, range(10))) == [0, 2, 4, 6, 8]
assert (x['hello'])({'hello': 'world'}) == 'world'
print("All good!")
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment