from typing import TypeVar, Callable

I = TypeVar("I")
O = TypeVar("O")

Function = Callable[[I], O]
"""
Represents a function that takes an input of type `I` and returns an output of type `O`.

Example:
    def square(x: int) -> int:
        return x * x

    f: Function[int, int] = square
"""

Predicate = Callable[[I], bool]
"""
Represents a boolean-valued function (predicate) that takes an input of type `I`.

Example:
    def is_even(x: int) -> bool:
        return x % 2 == 0

    p: Predicate[int] = is_even
"""

Supplier = Callable[[], I]
"""
Represents a function that takes no arguments and supplies a value of type `I`.

Example:
    def supply_five() -> int:
        return 5

    s: Supplier[int] = supply_five
"""
