import torch


def detach_hidden(h):
    """Wraps hidden states in new Tensors, to detach them from their history."""
    if isinstance(h, torch.Tensor):
        return h.detach()
    elif h is None:
        return h
    elif isinstance(h, list):
        return list(detach_hidden(v) for v in h)
    elif isinstance(h, tuple):
        return tuple(detach_hidden(v) for v in h)
    elif isinstance(h, dict):
        for k, v in h.items():
            h[k] = detach_hidden(v)
        return h
    else:
        return h