Quantcast
Channel: Functional pipeline using python with advance operators - Stack Overflow
Viewing all articles
Browse latest Browse all 2

Answer by Stuart for Functional pipeline using python with advance operators

$
0
0

Although this library is intended to facilitate FP in Python, it's not clear whether the library itself should be written using lots of FP.

This is one way to implement using classes (based on the list type) to tell the pipe function whether it needs to fork or reduce, and whether it is dealing with a single data item or a list of items.

This makes some limited use of FP style techniques such as the recursive calls to apply_func (allowing multiple forks within a pipeline).

class Forked(list):""" Contains a list of data after forking """class Fork(list):""" Contains a list of functions for forking """class Reducer(object):""" Contains a function for reducing forked data """    def __init__(self, func):        self.func = funcdef fork(*funcs):    return Fork(funcs)def reducer(func):""" Return a reducer form based on a function that accepts a        Forked list as its first argument """    return Reducer(func)   def apply_func(data, func):""" Apply a function to data which may be forked """    if isinstance(data, Forked):        return Forked(apply_func(datum, func) for datum in data)    else:        return func(data)def apply_form(data, form):""" Apply a pipeline form (which may be a function, fork, or reducer)         to the data """    if callable(form):        return apply_func(data, form)    elif isinstance(form, Fork):        return Forked(apply_func(data, func) for func in form)    elif isinstance(form, Reducer):        return form.func(data)def pipe(data, *forms):""" Apply a pipeline of function forms to data """    return reduce(apply_form, forms, data)

Examples of this in use:

def double(x): return x * 2def inc(x): return x + 1def dec(x): return x - 1def mult(L): return L[0] * L[1]print pipe(10, inc, double)    # 21print pipe(10, fork(dec, inc), double)  # [18, 22]print pipe(10, fork(dec, inc), double, reducer(mult))   # 396

EDIT: This can also be simplified a bit further by making fork a function that returns a function and reducer a class that creates objects mimicking a function. Then the separate Fork and Reducer classes are no longer needed.

class Forked(list):""" Contains a list of data after forking """def fork(*funcs):""" Return a function that will take data and output a forked    list of results of putting the data through several functions """    def inner(data):        return Forked(apply_form(data, func) for func in funcs)    return innerclass reducer(object):    def __init__(self, func):        self.func = func    def __call__(self, data):        return self.func(data)def apply_form(data, form):""" Apply a function or reducer to data which may be forked """    if isinstance(data, Forked) and not isinstance(form, reducer):        return Forked(apply_form(datum, form) for datum in data)    else:        return form(data)def pipe(data, *forms):""" Apply a pipeline of function forms to data """    return reduce(apply_form, forms, data)

Viewing all articles
Browse latest Browse all 2

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>