Created
April 28, 2015 13:44
-
-
Save BasicWolf/560a7326314b67d61353 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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