def zip_dict(a: Dict[str, A], b: Dict[str, B]) \
        -> Dict[str, Tuple[Optional[A], Optional[B]]]:
    """
    Combine the values within two dictionaries by key.

    :param a: The first dictionary.
    :param b: The second dictionary.
    :return: A dictionary containing all keys that appear in the union of a and
             b. Values are pairs where the first part is a's value for the key,
             and right second part b's value.
    """
    return {key: (a.get(key), b.get(key)) for key in a.keys() | b.keys()}