1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* SPDX-License-Identifier: MIT
* Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
*/
use crateHKT;
/// Building a structure from a sequence of values: the direction [`Foldable`](crate::Foldable)
/// cannot run.
///
/// `Foldable::fold` takes `F<A>` to a summary. Nothing on the surface takes a sequence of `A` back
/// to an `F<A>`, and a caller that produces values one at a time — a draw per sample, a row per
/// record — has to name a concrete container to put them in. Naming one is what forces a function
/// that should be generic in its carrier to pick a crate's container and stop being generic.
///
/// # Why no existing capability does this
///
/// Each of the neighbours covers a different direction, and the gap is not an oversight in any of
/// them.
///
/// - [`Foldable`](crate::Foldable) consumes a structure. It is this trait's opposite, and the two
/// compose into a round trip.
/// - [`Pure`](crate::Pure) builds a structure holding exactly one value. There is no operation on a
/// bare container to extend it by one more, so `pure` cannot be iterated into a sequence.
/// - [`Semigroupal::zip_with`](crate::Semigroupal::zip_with) pairs the slots two structures already
/// have. It never adds a slot, so it cannot grow a container from nothing.
/// - [`Monad::bind`](crate::Monad::bind) on a list-shaped witness does concatenate, so a fold over
/// `bind` could build one. That route is unavailable where it is most needed: `bind` requires
/// `Pure`, and the zip witnesses deliberately have none. It would also tie construction to the
/// cartesian reading, which is the wrong one for parallel runs.
///
/// # Laws (Informal)
///
/// 1. **Round trip**: `F::fold(F::collect(xs), init, f) == xs.into_iter().fold(init, f)` — collecting
/// a sequence and folding the result is folding the sequence, for any witness that also
/// implements [`Foldable`](crate::Foldable).
/// 2. **Order**: the i-th value of the sequence occupies the i-th slot of the structure. `collect`
/// preserves order; it is not a set.
/// 3. **Empty**: collecting no values yields the carrier's empty structure rather than failing, so
/// folding that structure returns the initial accumulator unchanged.
///
/// Laws are stated for pure functions; a stateful iterator voids them.
///
/// # Rank
///
/// For a carrier with a shape, `collect` produces the **rank-1** structure of the given length.
/// A carrier that can hold higher-rank data reshapes afterwards; deciding a shape from a flat
/// sequence is not something this operation can do, and guessing one would be wrong more often
/// than right.
///
/// # Type Parameters
///
/// * `F`: A Higher-Kinded Type (HKT) witness that represents the type constructor.