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

from remedapy.decorator import make_data_last

T = TypeVar('T')


@overload
def tap(fn: Callable[[T], Any], /) -> Callable[[T], T]: ...


@overload
def tap(value: T, fn: Callable[[T], Any], /) -> T: ...


@make_data_last
def tap(value: T, function: Callable[[T], Any], /) -> T | Callable[[T], T]:
    """
    Applies the givent function to the value and returns the value.

    Parameters
    ----------
    value : T
        Input value (positional-only).
    function: Callable[[T], Any]
        Function to apply to the value (positional-only).

    Returns
    -------
    T
        The value given


    Examples
    --------
    Data first:
    >>> acc = []
    >>> R.tap(5, lambda x: acc.append(x))
    5
    >>> acc
    [5]

    Data last:
    >>> acc = []
    >>> R.tap(lambda x: acc.append(x))(5)
    5
    >>> acc
    [5]

    """
    function(value)
    return value
