@dispatch((tuple, list, set, frozenset))
def discover(seq):
    if not seq:
        return var * string
    unite = do_one([unite_identical, unite_base, unite_merge_dimensions])
    # [(a, b), (a, c)]
    if (all(isinstance(item, (tuple, list)) for item in seq) and
            len(set(map(len, seq))) == 1):
        columns = list(zip(*seq))
        try:
            types = [unite([discover(data) for data in column]).subshape[0]
                     for column in columns]
            unite = do_one([unite_identical, unite_merge_dimensions, Tuple])
            return len(seq) * unite(types)
        except __HOLE__:  # no subshape available
            pass

    # [{k: v, k: v}, {k: v, k: v}]
    if all(isinstance(item, dict) for item in seq):
        keys = sorted(set.union(*(set(d) for d in seq)))
        columns = [[item.get(key) for item in seq] for key in keys]
        try:
            types = [unite([discover(data) for data in column]).subshape[0]
                     for column in columns]
            return len(seq) * Record(list(zip(keys, types)))
        except AttributeError:
            pass

    types = list(map(discover, seq))
    return do_one([unite_identical, unite_merge_dimensions, Tuple])(types)
dataset/ETHPy150Open blaze/datashape/datashape/discovery.py/discover