Return a sequence of tuples representing a probabilistic combination.

    A mixture is described by an iterable of tuples of the form

        (probability of object, object)

    The probability components of the tuples must sum to 1.0 and be between
    0 and 1 (inclusive).

    Args:
        val: The value whose mixture is being computed.
        default: A default value if val does not support mixture.

    Returns:
        An iterable of tuples of size 2. The first element of the tuple is a
        probability (between 0 and 1) and the second is the object that occurs
        with that probability in the mixture. The probabilities will sum to 1.0.

def mixture(
    val: Any,
    default: Any = RaiseTypeErrorIfNotProvided) -> Sequence[Tuple[float, Any]]:
    """Return a sequence of tuples representing a probabilistic combination.

    A mixture is described by an iterable of tuples of the form

        (probability of object, object)

    The probability components of the tuples must sum to 1.0 and be between
    0 and 1 (inclusive).

    Args:
        val: The value whose mixture is being computed.
        default: A default value if val does not support mixture.

    Returns:
        An iterable of tuples of size 2. The first element of the tuple is a
        probability (between 0 and 1) and the second is the object that occurs
        with that probability in the mixture. The probabilities will sum to 1.0.
    """

    getter = getattr(val, '_mixture_', None)
    result = NotImplemented if getter is None else getter()

    if result is not NotImplemented:
        return result
    if default is not RaiseTypeErrorIfNotProvided:
        return default

    if getter is None:
        raise TypeError(
            "object of type '{}' has no _mixture_ method.".format(type(val)))

    raise TypeError("object of type '{}' does have a _mixture_ method, "
                    "but it returned NotImplemented.".format(type(val)))