Created
August 9, 2016 11:44
-
-
Save nvbn/d71fee5b1cad58d5eb80e369194f4155 to your computer and use it in GitHub Desktop.
Partial application and piping without magic
This file contains hidden or 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 wraps | |
class Partial: | |
def __init__(self, fn, args, kwargs): | |
self._fn = fn | |
self._args = args | |
self._kwargs = kwargs | |
def __call__(self, replacement): | |
args = [replacement if arg is ... else arg | |
for arg in self._args] | |
kwargs = {key: replacement if val is ... else val | |
for key, val in self._kwargs.items()} | |
return self._fn(*args, **kwargs) | |
def __rmatmul__(self, replacement): | |
return self(replacement) | |
def __repr__(self): | |
return '<Partial: {}(*{}, **{})>'.format( | |
self._fn.__name__, repr(self._args), repr(self._kwargs)) | |
def ellipsis_partial(fn): | |
@wraps(fn) | |
def wrapper(*args, **kwargs): | |
ellipsises = (list(args) + list(kwargs.values())).count(...) | |
if ellipsises > 1: | |
raise TypeError('Only one ... allowed as an argument.') | |
elif ellipsises: | |
return Partial(fn, args, kwargs) | |
else: | |
return fn(*args, **kwargs) | |
return wrapper | |
def _(fn, *args, **kwargs): | |
return ellipsis_partial(fn)(*args, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment