Table of Contents

Method Fold

Namespace
SodaFlow.Collections
Assembly
SodaFlow.Collections.dll

Fold<TKey, TIdentity, TState, TAccumulate>(ReactiveCollection<TKey, TIdentity, TState>, Func<TIdentity, TState, TAccumulate>, TAccumulate, Func<TAccumulate, TAccumulate, TAccumulate>, Func<TAccumulate, TAccumulate, TAccumulate>)

Folds each item into one cell, and keeps that cell current as the collection changes.

public static Cell<TAccumulate> Fold<TKey, TIdentity, TState, TAccumulate>(this ReactiveCollection<TKey, TIdentity, TState> collection, Func<TIdentity, TState, TAccumulate> select, TAccumulate zero, Func<TAccumulate, TAccumulate, TAccumulate> add, Func<TAccumulate, TAccumulate, TAccumulate> subtract) where TKey : notnull where TIdentity : notnull

Parameters

collection ReactiveCollection<TKey, TIdentity, TState>

The collection or view to fold.

select Func<TIdentity, TState, TAccumulate>

The part of an item that this fold adds, from its identity and its state, such as a balance.

zero TAccumulate

The value for no items, which must be the identity of add.

add Func<TAccumulate, TAccumulate, TAccumulate>

Adds the value of one item to the accumulated value.

subtract Func<TAccumulate, TAccumulate, TAccumulate>

Removes the value of one item from the accumulated value. It must remove each value that add includes.

Returns

Cell<TAccumulate>

A cell with the folded value of the items that the collection holds.

Type Parameters

TKey

The type of the keys.

TIdentity

The type of the immutable part of an item.

TState

The type of the mutable part of an item.

TAccumulate

The type of the value that the fold gives.

Remarks

The cost of one edit is the count of the keys in that edit, and not the count of the items. Each change carries the states before it and the states after it. Thus, this code removes the previous value of a key and adds the new one. A fold written by hand usually reads the store again, which is O(n) for each edit.

add and subtract must make a group with zero: subtract must remove each value that add includes, and zero changes no value. A sum and a count are groups. A maximum is not one, because no function removes a value from a maximum, and this operation cannot give one. Read the first key of a view with a sort for that. The group must also be commutative: this code adds and subtracts in the sequence of the keys of a change.

TAccumulate is the type of the caller, thus a group gives more than a sum. A pair of a sum and a count, with a Map after it, gives an average. A map of one counter for each group gives a count for each group, where add adds one to a counter and subtract removes one. A select of 1 or 0 counts the items that a condition accepts, with no Filter stage. Where add and subtract are one function, such as exclusive or, the value is a fingerprint of the states.

A view folds its own items. The fold of a Filter stage adds an item as the filter accepts it, and removes the item as the filter refuses it. Thus, the value follows the view and not the store.

A floating-point type is a group that loses precision. Each edit adds one operation to the value. Thus, a long sequence of edits can move the value away from the sum of the items. Fold a decimal, or an integer of the smallest unit, where that matters: the Accounts sample holds a balance in cents for this cause.