fold

The seeded form of reduce: always safe, even on an empty pipeline.

Acc fold<A, Acc>(Acc seed, Acc Function(Acc acc, A a) f, Iterable<A> iterable) Future<Acc> foldAsync<A, Acc>(FutureOr<Acc> seed, FutureOr<Acc> Function(Acc acc, A a) f, FxAsyncIterable<A> iterable) Acc Fx.fold<Acc>(Acc initialValue, Acc Function(Acc acc, T a) combine) // chain (sync, inherited from Iterable) Future<Acc> FxAsync.fold<Acc>(FutureOr<Acc> seed, FutureOr<Acc> Function(Acc acc, T a) f) // chain (async)

Lecture

fold is reduce with an explicit starting value. In FxTS this is just reduce called with three arguments — reduce(f, seed, iterable). Dart can't tell overloads apart by argument count, so FxDart splits the two: the unseeded form keeps the name reduce, and the seeded form is renamed fold, matching the name Dart's own Iterable already uses for exactly this operation.

Note the argument order carefully: it's fold(seed, f, iterable) — seed first, then the combiner, then the source — mirroring Iterable.fold(initialValue, combine) on the chain form. That's different from FxTS's reduce(f, seed, iterable), where the function comes first.

Because you always supply the seed, fold never throws on an empty iterable — it just returns the seed unchanged. That makes it the safer default whenever you're not sure the pipeline has any elements at all. Like reduce, it's a terminal operator: nothing upstream runs until fold pulls it.

Demo 1 · Basics & empty input

Demo 2 · Async, building up a Map

The seed doesn't have to be a number — here we fold a delayed pipeline into a length histogram:

Try it yourself

Exercise: fold the deposits into a running balance, starting from 1000.

Related: reduce — the unseeded counterpart · reduceLazy — a reusable, curried reducer · sum — a common fold, specialized · scan — like fold, but lazily yields every intermediate value