Skip to content

Commit 852038b

Browse files
committed
feat(other): add functional programming pipeline implementation with unix pipeline syntax
1 parent b22fab0 commit 852038b

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

other/pipeline.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from collections.abc import Callable, Sequence
2+
from typing import Any, TypeVar
3+
4+
T = TypeVar("T")
5+
6+
7+
class Pipeline:
8+
"""
9+
Functional Programming implementation of a Pipeline with Unix Pipe Syntax.
10+
Instead of using the "dot" notation for applying a function on a given object,
11+
it uses `|` inspired from unix pipeline.
12+
13+
Examples:
14+
>>> pipeline = Pipeline()
15+
>>> pipeline = pipeline | (lambda x: x + 1) | (lambda x: x * 2)
16+
>>> pipeline(1)
17+
4
18+
>>> pipeline = Pipeline() | (lambda x: x * x) | (lambda x: x - 3)
19+
>>> pipeline(3)
20+
6
21+
>>> from functools import reduce
22+
>>> def f1(ls): return map(lambda x: x**2, ls)
23+
>>> def f2(ls): return filter(lambda x: x % 2 == 0, ls)
24+
>>> def f3(ls): return reduce(lambda x, y: x + y, ls)
25+
>>> pipeline = Pipeline() | f1 | f2 | f3
26+
>>> pipeline([1, 2, 3, 4])
27+
20
28+
"""
29+
30+
def __init__(self, f_ls: Sequence[Callable] | None = None):
31+
self._f_ls = f_ls or []
32+
33+
def __or__(self, other: Callable) -> "Pipeline":
34+
return Pipeline(f_ls=[*self._f_ls, other])
35+
36+
def __call__(self, x: T, f_ls_: Sequence[Callable] | None = None) -> Any:
37+
f_ls = f_ls_ or self._f_ls
38+
if len(f_ls) == 1:
39+
return f_ls[0](x)
40+
return self(f_ls[0](x), f_ls_=f_ls[1:])
41+
42+
43+
if __name__ == "__main__":
44+
import doctest
45+
46+
doctest.testmod()

0 commit comments

Comments
 (0)