Module better_functools.apply
Global variables
var func : Callable[[T], R]
-
Useful for creating a partial function of an argument which is not the last and not named.
Suppose we have a
fn: (a, b, c) -> d
arg(fn): (b, c) -> ((a) -> d)>>> def mod(a: int, b: int, /) -> int: ... return a % b >>> is_odd = func(mod @ func.arg(int) @ bind(2)) @ compose(bool) >>> is_odd @ invoke(5) True >>> is_odd(4) False
var nvl : T | None
-
None-Coalescing function.
nvl
is used in 2 ways.When used with
@
it checks the result of the left-hand side expression and ignores further@
operations ifNone
.When called it cleans up the result of an
@ nvl
chain.The operation should be used as
nvl(expr1 @ nvl @ expr2 @ nvl @ …)
>>> def squared(n: int) -> int: ... return n * n >>> def squared_or_none(v: int | None): ... return nvl(v @ nvl @ squared) >>> squared_or_none(5) 25 >>> squared_or_none(None) None
var star_args : Callable[[tuple[Unpack[Ts]]], R]
-
Convert a function with positional args to one that takes a single tuple.
This is useful when used with
Pipeline
.>>> def add(x: int, y: int) -> int: ... return x + y >>> (add @ star_args)((1, 2))
Functions
def static(fn: Callable[Concatenate[T, P], R]) ‑> Callable[~P, apply[Callable[[~T], ~R]]]
-
Expand source code
def static(fn: Callable[Concatenate[T, P], R]) -> Callable[P, apply[Callable[[T], R]]]: """*Experimental*: Make a bound method static. This makes it easier to chain the method. suppose you have a bound method on an object of type `MyType` ``` obj.method: (*args, **kwargs) -> ReturnType ``` Applying static: ``` static(MyType.method): (*args, **kwargs) -> ((MyType) -> ReturnType) ``` Example: >>> get_id = static(dict[str, int].__getitem__)("id") >>> get_id({"id": 1234}) 1234 Limitations: - Generics on the parent class maybe lost explicitly specify the generic type in such cases. - Does not work well with MyPy. """ def _outer(*args: P.args, **kwargs: P.kwargs) -> apply[Callable[[T], R]]: @apply def _inner(first: T) -> R: return fn(first, *args, **kwargs) return _inner return _outer
Experimental: Make a bound method static.
This makes it easier to chain the method.
suppose you have a bound method on an object of type
MyType
obj.method: (*args, **kwargs) -> ReturnType
Applying static:
static(MyType.method): (*args, **kwargs) -> ((MyType) -> ReturnType)
Example:
>>> get_id = static(dict[str, int].__getitem__)("id") >>> get_id({"id": 1234}) 1234
Limitations: - Generics on the parent class maybe lost explicitly specify the generic type in such cases. - Does not work well with MyPy.
Classes
class apply (fn: T_APPLY)
-
Expand source code
class apply(Generic[T_APPLY]): """Make a function callable by using `@` operator. This is the `@` version of `... | fn` in `better_functools.pipe.Composition`. >>> "1234" @ apply(int) 1234 """ def __init__(self, fn: T_APPLY) -> None: self.fn = fn if TYPE_CHECKING: __call__: T_APPLY __rmatmul__: T_APPLY else: def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) __rmatmul__ = __call__
Make a function callable by using
@
operator.This is the
@
version of... | fn
inComposition
.>>> "1234" @ apply(int) 1234
Ancestors
- typing.Generic
class bind (val: T)
-
Expand source code
@dataclass class bind(Generic[T]): """Bind the first argument to the function. >>> def add(x: int, y: int) -> int: ... return x + y >>> (add @ bind(2))(5) 7 """ val: T def __call__(self, fn: Callable[Concatenate[T, P], R]) -> Callable[P, R]: def _new_fn(*args: P.args, **kwargs: P.kwargs) -> R: return fn(self.val, *args, **kwargs) return _new_fn def __rmatmul__(self, fn: Callable[Concatenate[T, P], R]) -> Callable[P, R]: return self(fn)
Bind the first argument to the function.
>>> def add(x: int, y: int) -> int: ... return x + y >>> (add @ bind(2))(5) 7
Ancestors
- typing.Generic
Class variables
var val : ~T
class compose (fn: Callable[[T], R])
-
Expand source code
@dataclass class compose(Generic[T, R]): """Compose functions. This is similar to `better_functools.pipe.Composition`, but allows it to be done with `@`. >>> def add(x: int, y: int) -> int: ... return x + y >>> add_plus_one = add @ compose(add @ bind(1)) >>> add_plus_one(2, 3) 6 """ fn: Callable[[T], R] def __call__(self, other: Callable[P, T]) -> Callable[P, R]: def _call(*args: P.args, **kwargs: P.kwargs) -> R: return self.fn(other(*args, **kwargs)) return _call __rmatmul__ = __call__
Compose functions.
This is similar to
Composition
, but allows it to be done with@
.>>> def add(x: int, y: int) -> int: ... return x + y >>> add_plus_one = add @ compose(add @ bind(1)) >>> add_plus_one(2, 3) 6
Ancestors
- typing.Generic
Class variables
var fn : Callable[[~T], ~R]
class invoke (*args: Unpack[Ts])
-
Expand source code
class invoke(Generic[Unpack[Ts]]): """Invoke a function with the given positional args. This is useful when dealing with a `@` chain. >>> def add(x: int, y: int, z: int) -> int: ... return x + y + z >>> (add @ bind(1) @ bind(2))(3) # hard to read 6 >>> add @ bind(1) @ bind(2) @ invoke(3) 6 """ def __init__(self, *args: Unpack[Ts]) -> None: self.args = args def __call__(self, fn: Callable[[Unpack[Ts]], R]) -> R: return fn(*self.args) __rmatmul__ = __call__
Invoke a function with the given positional args.
This is useful when dealing with a
@
chain.>>> def add(x: int, y: int, z: int) -> int: ... return x + y + z >>> (add @ bind(1) @ bind(2))(3) # hard to read 6 >>> add @ bind(1) @ bind(2) @ invoke(3) 6
Ancestors
- typing.Generic