Iterates over arguments and calls approx_eq recursively.

    Types of `val` and `other` does not necessarily needs to match each other.
    They just need to be iterable of the same length and have the same
    structure, approx_eq() will be called on each consecutive element of `val`
    and `other`.

    Args:
        val: Source for approximate comparison.
        other: Target for approximate comparison.
        atol: The minimum absolute tolerance. See np.isclose() documentation for
              details.

    Returns:
        True if objects are approximately equal, False otherwise. Returns
        NotImplemented when approximate equality is not implemented for given
        types.

def _approx_eq_iterables(val: Any, other: Any, *,
                         atol: Union[int, float]) -> bool:
    """Iterates over arguments and calls approx_eq recursively.

    Types of `val` and `other` does not necessarily needs to match each other.
    They just need to be iterable of the same length and have the same
    structure, approx_eq() will be called on each consecutive element of `val`
    and `other`.

    Args:
        val: Source for approximate comparison.
        other: Target for approximate comparison.
        atol: The minimum absolute tolerance. See np.isclose() documentation for
              details.

    Returns:
        True if objects are approximately equal, False otherwise. Returns
        NotImplemented when approximate equality is not implemented for given
        types.
    """

    def get_iter(iterable):
        try:
            return iter(iterable)
        except TypeError:
            return None

    val_it = get_iter(val)
    other_it = get_iter(other)

    if val_it is not None and other_it is not None:
        while True:
            try:
                val_next = next(val_it)
            except StopIteration:
                try:
                    next(other_it)
                    return False
                except StopIteration:
                    return True

            try:
                other_next = next(other_it)
            except StopIteration:
                return False

            result = approx_eq(val_next, other_next, atol=atol)
            if result is not True:
                return result

    return NotImplemented