For a list-typed SArray, check whether the first elements are lists that
    - contain only the provided types
    - all have the same lengths (optionally)

    Parameters
    ----------
    sa : SArray
        An SArray containing lists.

    allowed_types : list
        A list of types that are allowed in each list.

    require_same_type : bool
        If true, the function returns false if more than one type of object
        exists in the examined lists.

    require_equal_length : bool
        If true, the function requires false when the list lengths differ.

    Returns
    -------
    out : bool
        Returns true if all elements are lists of equal length and containing
        only ints or floats. Otherwise returns false.

def _validate_lists(sa, allowed_types=[str], require_same_type=True,
                    require_equal_length=False, num_to_check=10):
    """
    For a list-typed SArray, check whether the first elements are lists that
    - contain only the provided types
    - all have the same lengths (optionally)

    Parameters
    ----------
    sa : SArray
        An SArray containing lists.

    allowed_types : list
        A list of types that are allowed in each list.

    require_same_type : bool
        If true, the function returns false if more than one type of object
        exists in the examined lists.

    require_equal_length : bool
        If true, the function requires false when the list lengths differ.

    Returns
    -------
    out : bool
        Returns true if all elements are lists of equal length and containing
        only ints or floats. Otherwise returns false.
    """
    if len(sa) == 0:
        return True

    first_elements = sa.head(num_to_check)
    if first_elements.dtype != list:
        raise ValueError("Expected an SArray of lists when type-checking lists.")

    # Check list lengths
    list_lengths = list(first_elements.item_length())
    same_length = _check_elements_equal(list_lengths)
    if require_equal_length and not same_length:
        return False

    # If list lengths are all zero, return True.
    if len(first_elements[0]) == 0:
        return True

    # Check for matching types within each list
    types = first_elements.apply(lambda xs: [str(type(x)) for x in xs])
    same_type = [_check_elements_equal(x) for x in types]
    all_same_type = _check_elements_equal(same_type)
    if require_same_type and not all_same_type:
        return False

    # Check for matching types across lists
    first_types = [t[0] for t in types if t]
    all_same_type = _check_elements_equal(first_types)
    if require_same_type and not all_same_type:
        return False

    # Check to make sure all elements have types that are allowed
    allowed_type_strs = [str(x) for x in allowed_types]
    for list_element_types in types:
        for t in list_element_types:
            if t not in allowed_type_strs:
                return False

    return True