from typing import Callable
from typing import Mapping


def map_tree(tree, map_fn: Callable):
    """
    Map one tree to another using a transformation function

    Args:
        tree: A sequence, mapping or other value
        map_fn (Callable): The function to apply to each node, returing the new value
    Returns:
        The transformed tree
    """
    if isinstance(tree, Mapping):
        return {key: map_tree(value, map_fn) for (key, value) in tree.items()}
    if isinstance(tree, (list, tuple)):
        return [map_tree(value, map_fn) for value in tree]
    return map_fn(tree)