Skip to content

Instantly share code, notes, and snippets.

@BasicWolf
Created April 28, 2015 13:44
Show Gist options
  • Save BasicWolf/560a7326314b67d61353 to your computer and use it in GitHub Desktop.
Save BasicWolf/560a7326314b67d61353 to your computer and use it in GitHub Desktop.
from functools import partial
itself = lambda x: x
plus = lambda x, y: x + y
minus = lambda x, y: x - y
class _FBase:
def __init__(self, f1=itself):
self.f1 = f1
def __add__(self, val):
if isinstance(val, _FBase):
return _FBinary(plus, self, val)
else:
return _FBase(partial(plus, val))
def __sub__(self, val):
if isinstance(val, _FBase):
return _FBinary(minus, self, val)
else:
return _FBase(partial(minus, 3))
def __call__(self, args):
if self._is_list_args(args) and len(args) == 1:
return self.f1(args[0])
else:
return self.f1(args)
def _is_list_args(self, args):
return isinstance(args, tuple) or isinstance(args, list)
class _FBinary(_FBase):
def __init__(self, op, f1, f2):
self.op = op
self.f1 = f1
self.f2 = f2
def __call__(self, args):
if self._is_list_args(args):
rest, last = args[:-1], args[-1]
ex, ey = self.f1(rest), self.f2(last)
return self.op(ex, ey)
class _FPos(_FBase):
def __init__(self, pos, f1=itself):
super(_FPos, self).__init__(f1)
self.pos = pos
def __add__(self, val):
if isinstance(val, _FBase):
return _FBinaryPos(plus, self, val)
else:
return _FPos(self.pos, partial(plus, val))
def __call__(self, args, pos_args=None):
if pos_args is None:
return self.f1(args[self.pos])
elif self._is_list_args(args) and len(args) == 1:
return self.f1(pos_args[self.pos])
else:
return pos_args[self.pos]
class _FBinaryPos(_FPos):
def __init__(self, op, f1, f2):
self.op = op
self.f1 = f1
self.f2 = f2
self.fpos = None
def __call__(self, args, pos_args=None):
# this happens only on the top-level call
if pos_args == None:
pos_args = args
if self._is_list_args(args):
rest, last = args[:-1], args[-1]
ex, ey = self.f1(rest, pos_args), self.f2(last, pos_args)
return self.op(ex, ey)
_ = _FBase()
_0 = _FPos(0)
_1 = _FPos(1)
_2 = _FPos(2)
m = map(_0 + _1 + _2, [(1, 2, 3)])
m = map(_ + 3, [1, 2, 3])
m = map(_ + _, [(1, 2), (2, 3), (3, 4)])
m = map(_ + _ - _, [(1, 2, 3), (2, 3, 4), (3, 4, 5)])
print(list(m))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment