"""EVA algebra — composition operators for BRIK-64 monomers."""
from typing import Any, Callable, TypeVar

A = TypeVar("A")
B = TypeVar("B")
C = TypeVar("C")


def seq(f: Callable[[A], B], g: Callable[[B], C]) -> Callable[[A], C]:
    """⊗ Sequential composition: g(f(x))."""
    def composed(x: A) -> C:
        return g(f(x))
    return composed


def par(f: Callable, g: Callable) -> Callable:
    """∥ Parallel composition: (f(a), g(b))."""
    def composed(a: Any, b: Any) -> tuple:
        return (f(a), g(b))
    return composed


def cond(pred: Callable[[Any], bool], then_f: Callable, else_f: Callable) -> Callable:
    """⊕ Conditional composition: pred(x) ? then_f(x) : else_f(x)."""
    def composed(x: Any) -> Any:
        return then_f(x) if pred(x) else else_f(x)
    return composed


def pipeline(*fns: Callable) -> Callable:
    """Chain multiple functions sequentially."""
    def composed(x: Any) -> Any:
        result = x
        for f in fns:
            result = f(result)
        return result
    return composed


def compose(*fns: Callable) -> Callable:
    """Compose functions right-to-left (mathematical convention)."""
    def composed(x: Any) -> Any:
        result = x
        for f in reversed(fns):
            result = f(result)
        return result
    return composed


__all__ = ["seq", "par", "cond", "pipeline", "compose"]
