import functools


def repeater(f):
    """
    Returns a generator function that returns a repeated function composition
    iterator (generator) for the function given, i.e., for a function input
    ``f`` with one parameter ``n``, calling ``repeater(f)(n)`` yields the
    values (one at a time)::

             n, f(n), f(f(n)), f(f(f(n))), ...

    Examples
    --------

    >>> func = repeater(lambda x: x ** 2 - 1)
    >>> func
    <function ...>
    >>> gen = func(3)
    >>> gen
    <generator object ...>
    >>> next(gen)
    3
    >>> next(gen) # 3 ** 2 - 1
    8
    >>> next(gen) # 8 ** 2 - 1
    63
    >>> next(gen) # 63 ** 2 - 1
    3968

    """

    @functools.wraps(f)
    def wrapper(n):
        val = n
        while True:
            yield val
            val = f(val)

    return wrapper