Closed evhub closed 7 months ago
We should also add
apply.using_processes = apply$(map_using=process_map)
apply.using_threads = apply$(map_using=thread_map)
apply.using_async = apply$(map_using=async_map)
Initial implementation for header:
class apply(_coconut_base_callable):
"""Given unary functions, create a new function that applies each function to its corresponding argument.
Thus, apply((.+1), (.*2)) is equivalent to (x, y) -> (x + 1, y * 2).
Effectively equivalent to:
def apply(*funcs, map_using=map) =
(*args) => map_using(call, funcs, args, strict=True)
"""
__slots__ = ("funcs", "map_using")
def __init__(self, *funcs, **kwargs):
self.funcs = funcs
self.map_using = kwargs.pop("map_using", None)
if kwargs:
raise _coconut.TypeError("apply() got unexpected keyword arguments " + _coconut.repr(kwargs))
def __reduce__(self):
return (self.__class__, self.funcs, {lbrace}"map_using": self.map_using{rbrace})
def __repr__(self):
return "apply(" + ", ".join(_coconut.repr(f) for f in self.funcs) + (", map_using=" + _coconut.repr(self.map_using) if self.map_using is not None else "") + ")"
def __call__(self, *args):
return ({_coconut_}map if self.map_using is None else self.map_using)({_coconut_}call, self.funcs, self.args, strict=True)
Alternatively, we could make something closer to lift
like
def comp(func) = (*func_args, **func_kwargs) => (*args, **kwargs) => (
func(
*map(call, func_args, args, strict=True),
**{k: func_kwargs[k](kwargs[k]) for k in func_kwargs.keys() | kwargs.keys()},
)
)
To encourage piping with branching, we should also add usage of
branch = lift(,)
branched = comp(,)
to the documentation.
For symmetry with lift, we could name it:
nlift
multi_lift
lift_args
lift_apart
Note that the usage is as the D2 combinator.
Added as lift_apart
.
~Maybe lift_args
is a better name than lift_apart
, actually.~
Should be equivalent to a pickleable version of