Higher order function creating a result type and collection function from
    the given metrics.

    Args:
        metrics (iterable): Sequence of callable metrics, each
            accepting the algorithm state as parameter and returning the
            measured value with its label:
            measurement(state) -> (label, value).

    Returns:
        tuple(dict, callable): dictionary result type and a collection
            function accepting the current results and the state as arguments
            and returning updated result.

    Examples:
        >>> state = State()
        >>> metrics = [lambda state_: state_.iterations]
        >>> (results, collect) = dictionary_based_metrics(metrics)
        >>> results = collect(results, state)

def dictionary_based_metrics(metrics):
    """
    Higher order function creating a result type and collection function from
    the given metrics.

    Args:
        metrics (iterable): Sequence of callable metrics, each
            accepting the algorithm state as parameter and returning the
            measured value with its label:
            measurement(state) -> (label, value).

    Returns:
        tuple(dict, callable): dictionary result type and a collection
            function accepting the current results and the state as arguments
            and returning updated result.

    Examples:
        >>> state = State()
        >>> metrics = [lambda state_: state_.iterations]
        >>> (results, collect) = dictionary_based_metrics(metrics)
        >>> results = collect(results, state)

    """

    def collect(results, state):
        """
        Measurement collection function for dictionary based metrics.

        Args:
            results (dict): Storing results of metrics.
            state (cipy.algorithms.core.State): Current state of the algorithm.

        Returns:
            dict: Updated results containing new metrics.
        """
        for measurement in metrics:
            (label, value) = measurement(state)
            iteration_dict = results.get(state.iterations, {})
            iteration_dict[label] = str(value)
            results[state.iterations] = iteration_dict
        return results

    return {}, collect