···
traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
# strict trace functions (traced structure is fully evaluated and printed)
24
+
/* `builtins.trace`, but the value is `builtins.deepSeq`ed first. */
traceSeq = x: y: trace (builtins.deepSeq x x) y;
27
+
/* Like `traceSeq`, but only down to depth n.
28
+
* This is very useful because lots of `traceSeq` usages
29
+
* lead to an infinite recursion.
31
+
traceSeqN = depth: x: y: with lib;
32
+
let snip = v: if isList v then noQuotes "[…]" v
33
+
else if isAttrs v then noQuotes "{…}" v
35
+
noQuotes = str: v: { __pretty = const str; val = v; };
36
+
modify = n: fn: v: if (n == 0) then fn v
37
+
else if isList v then map (modify (n - 1) fn) v
38
+
else if isAttrs v then mapAttrs
39
+
(const (modify (n - 1) fn)) v
41
+
in trace (generators.toPretty { allowPrettyValues = true; }
42
+
(modify depth snip x)) y;
44
+
/* `traceSeq`, but the same value is traced and returned */
traceValSeq = v: traceVal (builtins.deepSeq v v);
46
+
/* `traceValSeq` but with fixed depth */
47
+
traceValSeqN = depth: v: traceSeqN depth v v;
# this can help debug your code as well - designed to not produce thousands of lines
traceShowVal = x: trace (showVal x) x;