fix(builtins.zipAttrsWith): laziness
This commit is contained in:
@@ -107,3 +107,36 @@ export const groupBy =
|
||||
}
|
||||
return attrs;
|
||||
};
|
||||
|
||||
export const zipAttrsWith =
|
||||
(f: NixValue) =>
|
||||
(list: NixValue): NixValue => {
|
||||
const listForced = forceList(list);
|
||||
|
||||
// Map to collect all values for each attribute name
|
||||
const attrMap = new Map<string, NixValue[]>();
|
||||
|
||||
// Iterate through each attribute set in the list
|
||||
for (const item of listForced) {
|
||||
const attrs = forceAttrs(item);
|
||||
|
||||
// Collect all attribute names and their values
|
||||
for (const [key, value] of Object.entries(attrs)) {
|
||||
if (!attrMap.has(key)) {
|
||||
attrMap.set(key, []);
|
||||
}
|
||||
attrMap.get(key)!.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the result attribute set
|
||||
const result: Record<string, NixValue> = {};
|
||||
|
||||
for (const [name, values] of attrMap.entries()) {
|
||||
// Apply f to name and values list
|
||||
// f is curried: f name values
|
||||
result[name] = createThunk(() => forceFunction(forceFunction(f)(name))(values));
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -172,6 +172,7 @@ export const builtins: any = {
|
||||
intersectAttrs: mkPrimop(attrs.intersectAttrs, "intersectAttrs", 2),
|
||||
catAttrs: mkPrimop(attrs.catAttrs, "catAttrs", 2),
|
||||
groupBy: mkPrimop(attrs.groupBy, "groupBy", 2),
|
||||
zipAttrsWith: mkPrimop(attrs.zipAttrsWith, "zipAttrsWith", 2),
|
||||
|
||||
stringLength: mkPrimop(string.stringLength, "stringLength", 1),
|
||||
substring: mkPrimop(string.substring, "substring", 3),
|
||||
@@ -247,7 +248,6 @@ export const builtins: any = {
|
||||
splitVersion: mkPrimop(misc.splitVersion, "splitVersion", 1),
|
||||
traceVerbose: mkPrimop(misc.traceVerbose, "traceVerbose", 2),
|
||||
tryEval: mkPrimop(misc.tryEval, "tryEval", 1),
|
||||
zipAttrsWith: mkPrimop(misc.zipAttrsWith, "zipAttrsWith", 2),
|
||||
|
||||
builtins: createThunk(() => builtins, "builtins"),
|
||||
currentSystem: createThunk(() => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Miscellaneous builtin functions
|
||||
*/
|
||||
|
||||
import { force } from "../thunk";
|
||||
import { createThunk, force } from "../thunk";
|
||||
import { CatchableError } from "../types";
|
||||
import type { NixAttrs, NixBool, NixStrictValue, NixValue } from "../types";
|
||||
import { forceList, forceAttrs, forceFunction, forceStringValue, forceString } from "../type-assert";
|
||||
@@ -355,37 +355,3 @@ export const tryEval = (e: NixValue): { success: NixBool; value: NixStrictValue
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const zipAttrsWith =
|
||||
(f: NixValue) =>
|
||||
(list: NixValue): NixValue => {
|
||||
const listForced = forceList(list);
|
||||
|
||||
// Map to collect all values for each attribute name
|
||||
const attrMap = new Map<string, NixValue[]>();
|
||||
|
||||
// Iterate through each attribute set in the list
|
||||
for (const item of listForced) {
|
||||
const attrs = forceAttrs(force(item) as NixValue);
|
||||
|
||||
// Collect all attribute names and their values
|
||||
for (const [key, value] of Object.entries(attrs)) {
|
||||
if (!attrMap.has(key)) {
|
||||
attrMap.set(key, []);
|
||||
}
|
||||
attrMap.get(key)!.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the result attribute set
|
||||
const result: Record<string, NixValue> = {};
|
||||
|
||||
for (const [name, values] of attrMap.entries()) {
|
||||
// Apply f to name and values list
|
||||
// f is curried: f name values
|
||||
const fWithName = forceFunction(f)(name);
|
||||
result[name] = forceFunction(fWithName)(values);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user