from collections.abc import Callable
from typing import Any, TypeVar, overload

from remedapy.decorator import make_data_last

T = TypeVar('T')


@overload
def is_callable() -> Callable[[Any], bool]: ...


@overload
def is_callable(value: Any, /) -> bool: ...


@make_data_last
def is_callable(value: Any, /) -> bool:
    """
    A function that checks if the passed parameter is a callable and narrows its type accordingly.

    Alias to `isinstance(value, Callable)`.

    Parameters
    ----------
    value: Any
        Value to check.

    Returns
    -------
    result: bool
        Whether the value passed is an integer.

    Examples
    --------
    Data first:
    >>> R.is_callable(lambda x: x + 1)
    True
    >>> R.is_callable(R.is_callable)
    True
    >>> R.is_callable(True)
    False

    Data last:
    >>> R.is_callable()(R.add(3))
    True
    >>> R.is_callable()(2137)
    False

    """
    return isinstance(value, Callable)
