Transpose
What it does
Section titled “What it does”transpose swaps the outer two levels of a nested attribute set:
transpose { a.b.c = 1; }# ⇒ { b.a.c = 1; }Values below the second level are preserved as-is. Common children merge under one parent:
transpose { a.x = 1; b.x = 2; }# ⇒ { x = { a = 1; b = 2; }; }The implementation is a three-phase pipeline:
- Deconstruct —
mapAttrsToListover all parents, producing{ child, parent, value }items viaemit. - Flatten — collapse the nested lists into a flat list.
- Reconstruct —
foldlitems back into the transposed structure.
The emit hook
Section titled “The emit hook”emit is a function { child, parent, value } → [{ parent, child, value }].
Default is lib.singleton — identity transformation, one-to-one mapping.
You can use emit to:
- Filter: return
[]to drop items during transposition. - Modify: change the value, rename parent/child.
- Multiply: return multiple items from a single input.
How aspects exploit emit
Section titled “How aspects exploit emit”nix/aspects.nix supplies a custom emit that calls resolve on each item:
emit = transposed: [{ inherit (transposed) parent child; value = aspects.${transposed.child}.resolve { class = transposed.parent; };}];This intercepts every <aspect>.<class> → <class>.<aspect> transposition and replaces the raw value with a fully-resolved module that includes all transitive dependencies.