variant of tree mapstructure that operates on shape tuples if isshapetuplestruct return fntuplestruct if isinstancestruct list return mapshapestructurefn e for e in struct if isinstancestruct tuple return tuplemapshapestructurefn e for e in struct if isinstancestruct dict return k mapshapestructurefn v for k v in struct items else raise valueerrorfcannot map function to unknown object struct variant of tree map_structure that operates on shape tuples
def is_shape_tuple(x):
    if isinstance(x, (list, tuple)):
        if all(isinstance(e, (int, type(None))) for e in x):
            return True
    return False


def map_shape_structure(fn, struct):
    
    if is_shape_tuple(struct):
        return fn(tuple(struct))
    if isinstance(struct, list):
        return [map_shape_structure(fn, e) for e in struct]
    if isinstance(struct, tuple):
        return tuple(map_shape_structure(fn, e) for e in struct)
    if isinstance(struct, dict):
        return {k: map_shape_structure(fn, v) for k, v in struct.items()}
    else:
        raise ValueError(f"Cannot map function to unknown object {struct}")