from typing import Union


def cast_range_argument(arg: str) -> Union[int, float, str]:
    """
    Determine whether a range argument is integral, floating-point, or categorical.

    Parameters
    ----------
    arg
        The argument to check.

    Returns
    -------
    int
        If `arg` is castable to an integer.
    float
        If `arg` is castable to floating-point, but not an integer.
    string
        If `arg` is not castable to a numeric type.
    """

    try:
        return int(arg)
    except ValueError:
        try:
            return float(arg)
        except ValueError:
            return arg