<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def roll(*args, **kwargs):
 """ Calculates a given statistic across a rolling time period. Parameters returns : pd.Series or np.ndarray Daily returns of the strategy, noncumulative. - See full explanation in :func:`~empyrical.stats.cum_returns`. factor_returns (optional):
 float / series Benchmark return to compare returns against. function: the function to run for each rolling window. window (keyword):
 int the number of periods included in each calculation. (other keywords):
 other keywords that are required to be passed to the function in the 'function' argument may also be passed in. Returns ------- np.ndarray, pd.Series depends on input type ndarray(s) ==> ndarray Series(s) ==> pd.Series A Series or ndarray of the results of the stat across the rolling window. """

    func = kwargs.pop('function')
    window = kwargs.pop('window')
    if len(args) > 2:
        raise ValueError("Cannot pass more than 2 return sets")

    if len(args) == 2:
        if not isinstance(args[0], type(args[1])):
            raise ValueError("The two returns arguments are not the same.")

    if isinstance(args[0], np.ndarray):
        return _roll_ndarray(func, window, *args, **kwargs)
    return _roll_pandas(func, window, *args, **kwargs)