Search code examples
c#functional-programmingnomenclature

Standard function for iteratively accumulating while yielding related values


There's a particular style of computation that comes up now and then, that I don't know how to nicely translate into map/filter/reduce. I'm wondering if there's a standard functional-style function to do it, or what a good name is.

Basically, you find yourself following directions while yielding things at each stop. Here's a C# function showing the general idea:

public static IEnumerable<TOut> streamAggregateMap<TDif, TAcc, TOut>(
        this IEnumerable<TDif> difs,
        TAcc seed,
        Func<TAcc, TDif, TAcc> accumulator,
        Func<TAcc, TDif, TOut> selector) {
    var acc = seed;
    foreach (var dif in difs) {
        yield return selector(acc, dif);
        acc = accumulator(acc, dif);
    }
}

You can use it to trace down a tree while yielding values:

var vals = goLeftDirections.streamAggregateMap(
    root,
    (node, goLeft) => goLeft ? node.left : node.right,
    (node, goLeft) => node.value);

Or tell you the prime factorizations of numbers you get by iteratively multiplying by 2 and adding some offsets, except the factorizations are of numbers offset without multiplying by 2:

var factorizations = offsets.streamAggregateMap(
    1,
    (total, offset) => total * 2 + offset,
    (total, offset) => (total + offset).Factorize());

Is there a standard name for this "accumulate while yielding related values" functionality? A standard function to use?


Solution

  • MoreLINQ calls this operation Scan.