Functools Module¶
Functional programming utilities.
This module provides utility functions for functional programming patterns, including function composition, folding, currying, and more.
The F class serves as a namespace for these utilities, providing
static methods that can be used throughout your functional code.
F Class¶
- class katharos.functools.F[source]¶
Bases:
objectNamespace for utility functions.
All functions are static and can be called without instantiating the class.
- static compose(f)[source]¶
Compose two functions.
- Parameters:
f (
Callable[[TypeVar(B)],TypeVar(C)]) – A function from B to C.- Return type:
Callable[[Callable[[TypeVar(A)],TypeVar(B)]],Callable[[TypeVar(A)],TypeVar(C)]]- Returns:
A function that takes a function from A to B and returns a function from A to C.
Examples
>>> inc = lambda x: x + 1 >>> double = lambda x: x * 2 >>> inc_then_double = F.compose(double)(inc) >>> inc_then_double(5) 12
- static foldr(f, acc, xs)[source]¶
Right fold a function over an iterable.
- Parameters:
- Return type:
TypeVar(B)- Returns:
The accumulator value after applying f to each element of xs.
Examples
>>> F.foldr(lambda x, acc: acc + [x], [], [1, 2, 3]) [3, 2, 1] >>> F.foldr(lambda x, acc: f"({x}+{acc})", "0", [1, 2, 3]) '(1+(2+(3+0)))'
- static foldl(f, acc, xs)[source]¶
Left fold a function over an iterable.
- Parameters:
- Return type:
TypeVar(B)- Returns:
The accumulator value after applying f to each element of xs.
Examples
>>> F.foldl(lambda acc, x: acc + x, 0, [1, 2, 3]) 6 >>> F.foldl(lambda acc, x: f"({acc}+{x})", "0", [1, 2, 3]) '(((0+1)+2)+3)'
- static sigma(xs)[source]¶
Combine all elements of a non-empty list using the semigroup operation.
- Parameters:
xs (
NonEmptyList[TypeVar(A, bound=Semigroup)]) – A non-empty list of semigroup elements.- Return type:
- Returns:
The result of combining all elements using the semigroup’s @ operator.
Examples
>>> from katharos.types.list import NonEmptyList >>> from katharos.types.monoid import Sum >>> F.sigma(NonEmptyList(Sum(1), [Sum(2), Sum(3)])) Sum(6)
- static curry(f)[source]¶
- Overloads:
f (Callable[[A], R]) → Callable[[A], R]
f (Callable[[A, B], R]) → Callable[[A], Callable[[B], R]]
f (Callable[[A, B, C], R]) → Callable[[A], Callable[[B], Callable[[C], R]]]
f (Callable[…, Any]) → Callable[…, Any]
Transform a multi-argument function into a curried version.
Currying converts a function that takes multiple arguments into a sequence of functions, each taking a single argument. Supports both positional and keyword arguments, and several arguments may be supplied in one step.
The original function is invoked as soon as every parameter without a default is bound. Consequently, parameters with defaults (as well as
*args/**kwargs) can only be overridden in the step that completes the call — not in a later step, because there is no later step.- Parameters:
- Returns:
A curried version of the function.
- Raises:
TypeError – If an argument does not match the function’s signature, or a keyword argument is supplied more than once.
- Return type:
Examples
>>> def add(x: int, y: int, z: int) -> int: ... return x + y + z >>> curried_add = F.curry(add) >>> curried_add(1)(2)(3) 6 >>> add_one = curried_add(1) >>> add_one(2)(3) 6 >>> curried_add(x=1)(y=2)(z=3) 6 >>> curried_add(1, y=2)(z=3) 6
Parameters with defaults need not be supplied; the call fires once all required parameters are bound:
>>> def greet(name: str, greeting: str = "hi") -> str: ... return f"{greeting} {name}" >>> F.curry(greet)("bob") 'hi bob' >>> F.curry(greet)("bob", greeting="hello") 'hello bob'
Supplying the same keyword twice is an error, as in a plain call:
>>> curried_add(x=1)(x=2, y=2, z=3) Traceback (most recent call last): ... TypeError: f.add() got multiple values for keyword argument 'x'
- static lift_a2(f, fa, fb)[source]¶
Lift a binary function into an applicative context.
Applies a two-argument function to the values held inside two applicatives of the same type, combining their contexts.
- Parameters:
f (
Callable[[TypeVar(A),TypeVar(B)],TypeVar(C)]) – A function taking two arguments of types A and B.fa (
Applicative[TypeVar(App, bound=Applicative),TypeVar(A)]) – An applicative containing a value of type A.fb (
Applicative[TypeVar(App, bound=Applicative),TypeVar(B)]) – An applicative containing a value of type B.
- Return type:
Applicative[TypeVar(App, bound=Applicative),TypeVar(C)]- Returns:
An applicative containing the result of applying f to the two wrapped values.
Examples
>>> from katharos.types.maybe import Maybe >>> F.lift_a2(lambda x, y: x + y, Maybe.Just(2), Maybe.Just(3)) Just(5) >>> F.lift_a2(lambda x, y: x + y, Maybe.Just(2), Maybe.Nothing()) Nothing()
- static lift_a3(f, fa, fb, fc)[source]¶
Lift a ternary function into an applicative context.
Applies a three-argument function to the values held inside three applicatives of the same type, combining their contexts.
- Parameters:
f (
Callable[[TypeVar(A),TypeVar(B),TypeVar(C)],TypeVar(D)]) – A function taking three arguments of types A, B and C.fa (
Applicative[TypeVar(App, bound=Applicative),TypeVar(A)]) – An applicative containing a value of type A.fb (
Applicative[TypeVar(App, bound=Applicative),TypeVar(B)]) – An applicative containing a value of type B.fc (
Applicative[TypeVar(App, bound=Applicative),TypeVar(C)]) – An applicative containing a value of type C.
- Return type:
Applicative[TypeVar(App, bound=Applicative),TypeVar(D)]- Returns:
An applicative containing the result of applying f to the three wrapped values.
Examples
>>> from katharos.types.maybe import Maybe >>> F.lift_a3( ... lambda x, y, z: x + y + z, ... Maybe.Just(1), ... Maybe.Just(2), ... Maybe.Just(3), ... ) Just(6) >>> F.lift_a3( ... lambda x, y, z: x + y + z, ... Maybe.Just(1), ... Maybe.Nothing(), ... Maybe.Just(3), ... ) Nothing()