> a |> zip(b) |> map(func1) |> filter(func2) |> forall(func3)
The advantages would be that this would work with all lists/iterables, so no need to make a special types.
> a |> zip(b) |> map(func1) |> filter(func2) |> forall(func3)
The advantages would be that this would work with all lists/iterables, so no need to make a special types.
In short: it's a lot more complicated than it seems, but I agree that this style makes this type of thing 1000x more readable.
Pandas allows the first param in a pipe to be a tuple[callable, str], where the second argument would signify the parameter location, e.g. `val |> (func, "param_name")` which gives some flexibility.
But yeah, if you open up to piping, there are a lot of possible choices to be made and easy to go overboard also IMO.
from functools import partial
a |> partial(zip, b) |> partial(map, func1) |> partial(filter, func2) |> partial(forall, func3)
Obviously it's a bit more verbose than if the currying was done implicitly, but it's not too bad, I think. You could also import partial under a shorter name if you want.partial does have an advantage over implicit currying in that you can use keyword arguments to neatly curry on a parameter other than the first, although this isn't properly utilized by Python because most of the built-in functions have place-based rather than keyword arguments. In languages with implicit currying you have to use anonymous function expressions or functions like flip (flip(f, x, y) = f(y, x)) to deal with this.
It might also be worth noting that |> doesn't essentially need to be an operator, it would just be syntactic sugar:
def chain(x, *fs):
y = x
for f in fs:
y = f(x)
return y
chain(a, partial(zip, b), partial(map, func1), partial(filter, func2), partial(forall, func3))
Obviously having it as an infix operator is nicer, and produces less parentheses.