···11# General list operations.
22+23{ lib }:
34with lib.trivial;
45let
···89910 inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
10111111- /* Create a list consisting of a single element. `singleton x' is
1212- sometimes more convenient with respect to indentation than `[x]'
1212+ /* Create a list consisting of a single element. `singleton x` is
1313+ sometimes more convenient with respect to indentation than `[x]`
1314 when x spans multiple lines.
14151616+ Type: singleton :: a -> [a]
1717+1518 Example:
1619 singleton "foo"
1720 => [ "foo" ]
1821 */
1922 singleton = x: [x];
20232121- /* “right fold” a binary function `op' between successive elements of
2222- `list' with `nul' as the starting value, i.e.,
2323- `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'.
2424- Type:
2525- foldr :: (a -> b -> b) -> b -> [a] -> b
2424+ /* “right fold” a binary function `op` between successive elements of
2525+ `list` with `nul' as the starting value, i.e.,
2626+ `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.
2727+2828+ Type: foldr :: (a -> b -> b) -> b -> [a] -> b
26292730 Example:
2831 concat = foldr (a: b: a + b) "z"
···4245 else op (elemAt list n) (fold' (n + 1));
4346 in fold' 0;
44474545- /* `fold' is an alias of `foldr' for historic reasons */
4848+ /* `fold` is an alias of `foldr` for historic reasons */
4649 # FIXME(Profpatsch): deprecate?
4750 fold = foldr;
485149525050- /* “left fold”, like `foldr', but from the left:
5353+ /* “left fold”, like `foldr`, but from the left:
5154 `foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
52555353- Type:
5454- foldl :: (b -> a -> b) -> b -> [a] -> b
5656+ Type: foldl :: (b -> a -> b) -> b -> [a] -> b
55575658 Example:
5759 lconcat = foldl (a: b: a + b) "z"
···7072 else op (foldl' (n - 1)) (elemAt list n);
7173 in foldl' (length list - 1);
72747373- /* Strict version of `foldl'.
7575+ /* Strict version of `foldl`.
74767577 The difference is that evaluation is forced upon access. Usually used
7678 with small whole results (in contract with lazily-generated list or large
7779 lists where only a part is consumed.)
8080+8181+ Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
7882 */
7983 foldl' = builtins.foldl' or foldl;
80848185 /* Map with index starting from 0
82868787+ Type: imap0 :: (int -> a -> b) -> [a] -> [b]
8888+8389 Example:
8490 imap0 (i: v: "${v}-${toString i}") ["a" "b"]
8591 => [ "a-0" "b-1" ]
···8793 imap0 = f: list: genList (n: f n (elemAt list n)) (length list);
88948995 /* Map with index starting from 1
9696+9797+ Type: imap1 :: (int -> a -> b) -> [a] -> [b]
90989199 Example:
92100 imap1 (i: v: "${v}-${toString i}") ["a" "b"]
···95103 imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
9610497105 /* Map and concatenate the result.
106106+107107+ Type: concatMap :: (a -> [b]) -> [a] -> [b]
9810899109 Example:
100110 concatMap (x: [x] ++ ["z"]) ["a" "b"]
···118128119129 /* Remove elements equal to 'e' from a list. Useful for buildInputs.
120130131131+ Type: remove :: a -> [a] -> [a]
132132+121133 Example:
122134 remove 3 [ 1 3 4 3 ]
123135 => [ 1 4 ]
124136 */
125125- remove = e: filter (x: x != e);
137137+ remove =
138138+ # Element to remove from the list
139139+ e: filter (x: x != e);
126140127141 /* Find the sole element in the list matching the specified
128128- predicate, returns `default' if no such element exists, or
129129- `multiple' if there are multiple matching elements.
142142+ predicate, returns `default` if no such element exists, or
143143+ `multiple` if there are multiple matching elements.
144144+145145+ Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a
130146131147 Example:
132148 findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
···136152 findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
137153 => "none"
138154 */
139139- findSingle = pred: default: multiple: list:
155155+ findSingle =
156156+ # Predicate
157157+ pred:
158158+ # Default value to return if element was not found.
159159+ default:
160160+ # Default value to return if more than one element was found
161161+ multiple:
162162+ # Input list
163163+ list:
140164 let found = filter pred list; len = length found;
141165 in if len == 0 then default
142166 else if len != 1 then multiple
143167 else head found;
144168145169 /* Find the first element in the list matching the specified
146146- predicate or returns `default' if no such element exists.
170170+ predicate or return `default` if no such element exists.
171171+172172+ Type: findFirst :: (a -> bool) -> a -> [a] -> a
147173148174 Example:
149175 findFirst (x: x > 3) 7 [ 1 6 4 ]
···151177 findFirst (x: x > 9) 7 [ 1 6 4 ]
152178 => 7
153179 */
154154- findFirst = pred: default: list:
180180+ findFirst =
181181+ # Predicate
182182+ pred:
183183+ # Default value to return
184184+ default:
185185+ # Input list
186186+ list:
155187 let found = filter pred list;
156188 in if found == [] then default else head found;
157189158158- /* Return true iff function `pred' returns true for at least element
159159- of `list'.
190190+ /* Return true if function `pred` returns true for at least one
191191+ element of `list`.
192192+193193+ Type: any :: (a -> bool) -> [a] -> bool
160194161195 Example:
162196 any isString [ 1 "a" { } ]
···166200 */
167201 any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false);
168202169169- /* Return true iff function `pred' returns true for all elements of
170170- `list'.
203203+ /* Return true if function `pred` returns true for all elements of
204204+ `list`.
205205+206206+ Type: all :: (a -> bool) -> [a] -> bool
171207172208 Example:
173209 all (x: x < 3) [ 1 2 ]
···177213 */
178214 all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true);
179215180180- /* Count how many times function `pred' returns true for the elements
181181- of `list'.
216216+ /* Count how many elements of `list` match the supplied predicate
217217+ function.
218218+219219+ Type: count :: (a -> bool) -> [a] -> int
182220183221 Example:
184222 count (x: x == 3) [ 3 2 3 4 6 ]
185223 => 2
186224 */
187187- count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
225225+ count =
226226+ # Predicate
227227+ pred: foldl' (c: x: if pred x then c + 1 else c) 0;
188228189229 /* Return a singleton list or an empty list, depending on a boolean
190230 value. Useful when building lists with optional elements
191231 (e.g. `++ optional (system == "i686-linux") flashplayer').
232232+233233+ Type: optional :: bool -> a -> [a]
192234193235 Example:
194236 optional true "foo"
···200242201243 /* Return a list or an empty list, depending on a boolean value.
202244245245+ Type: optionals :: bool -> [a] -> [a]
246246+203247 Example:
204248 optionals true [ 2 3 ]
205249 => [ 2 3 ]
206250 optionals false [ 2 3 ]
207251 => [ ]
208252 */
209209- optionals = cond: elems: if cond then elems else [];
253253+ optionals =
254254+ # Condition
255255+ cond:
256256+ # List to return if condition is true
257257+ elems: if cond then elems else [];
210258211259212260 /* If argument is a list, return it; else, wrap it in a singleton
···223271224272 /* Return a list of integers from `first' up to and including `last'.
225273274274+ Type: range :: int -> int -> [int]
275275+226276 Example:
227277 range 2 4
228278 => [ 2 3 4 ]
229279 range 3 2
230280 => [ ]
231281 */
232232- range = first: last:
282282+ range =
283283+ # First integer in the range
284284+ first:
285285+ # Last integer in the range
286286+ last:
233287 if first > last then
234288 []
235289 else
236290 genList (n: first + n) (last - first + 1);
237291238238- /* Splits the elements of a list in two lists, `right' and
239239- `wrong', depending on the evaluation of a predicate.
292292+ /* Splits the elements of a list in two lists, `right` and
293293+ `wrong`, depending on the evaluation of a predicate.
294294+295295+ Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
240296241297 Example:
242298 partition (x: x > 2) [ 5 1 2 3 4 ]
···252308 /* Splits the elements of a list into many lists, using the return value of a predicate.
253309 Predicate should return a string which becomes keys of attrset `groupBy' returns.
254310255255- `groupBy'' allows to customise the combining function and initial value
311311+ `groupBy'` allows to customise the combining function and initial value
256312257313 Example:
258314 groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
···268324 xfce = [ { name = "xfce"; script = "xfce4-session &"; } ];
269325 }
270326271271-272272- groupBy' allows to customise the combining function and initial value
273273-274274- Example:
275327 groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
276328 => { true = 12; false = 3; }
277329 */
···289341 the merging stops at the shortest. How both lists are merged is defined
290342 by the first argument.
291343344344+ Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]
345345+292346 Example:
293347 zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
294348 => ["he" "lo"]
295349 */
296296- zipListsWith = f: fst: snd:
350350+ zipListsWith =
351351+ # Function to zip elements of both lists
352352+ f:
353353+ # First list
354354+ fst:
355355+ # Second list
356356+ snd:
297357 genList
298358 (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
299359300360 /* Merges two lists of the same size together. If the sizes aren't the same
301361 the merging stops at the shortest.
302362363363+ Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
364364+303365 Example:
304366 zipLists [ 1 2 ] [ "a" "b" ]
305367 => [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
···308370309371 /* Reverse the order of the elements of a list.
310372373373+ Type: reverseList :: [a] -> [a]
374374+311375 Example:
312376313377 reverseList [ "b" "o" "j" ]
···321385 `before a b == true` means that `b` depends on `a` (there's an
322386 edge from `b` to `a`).
323387324324- Examples:
325325-388388+ Example:
326389 listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
327390 == { minimal = "/"; # minimal element
328391 visited = [ "/home/user" ]; # seen elements (in reverse order)
···336399 rest = [ "/home" "other" ]; # everything else
337400338401 */
339339-340402 listDfs = stopOnCycles: before: list:
341403 let
342404 dfs' = us: visited: rest:
···361423 `before a b == true` means that `b` should be after `a`
362424 in the result.
363425364364- Examples:
426426+ Example:
365427366428 toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
367429 == { result = [ "/" "/home" "/home/user" "other" ]; }
···376438 toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
377439378440 */
379379-380441 toposort = before: list:
381442 let
382443 dfsthis = listDfs true before list;
···467528468529 /* Return the first (at most) N elements of a list.
469530531531+ Type: take :: int -> [a] -> [a]
532532+470533 Example:
471534 take 2 [ "a" "b" "c" "d" ]
472535 => [ "a" "b" ]
473536 take 2 [ ]
474537 => [ ]
475538 */
476476- take = count: sublist 0 count;
539539+ take =
540540+ # Number of elements to take
541541+ count: sublist 0 count;
477542478543 /* Remove the first (at most) N elements of a list.
544544+545545+ Type: drop :: int -> [a] -> [a]
479546480547 Example:
481548 drop 2 [ "a" "b" "c" "d" ]
···483550 drop 2 [ ]
484551 => [ ]
485552 */
486486- drop = count: list: sublist count (length list) list;
553553+ drop =
554554+ # Number of elements to drop
555555+ count:
556556+ # Input list
557557+ list: sublist count (length list) list;
487558488488- /* Return a list consisting of at most ‘count’ elements of ‘list’,
489489- starting at index ‘start’.
559559+ /* Return a list consisting of at most `count` elements of `list`,
560560+ starting at index `start`.
561561+562562+ Type: sublist :: int -> int -> [a] -> [a]
490563491564 Example:
492565 sublist 1 3 [ "a" "b" "c" "d" "e" ]
···494567 sublist 1 3 [ ]
495568 => [ ]
496569 */
497497- sublist = start: count: list:
570570+ sublist =
571571+ # Index at which to start the sublist
572572+ start:
573573+ # Number of elements to take
574574+ count:
575575+ # Input list
576576+ list:
498577 let len = length list; in
499578 genList
500579 (n: elemAt list (n + start))
···503582 else count);
504583505584 /* Return the last element of a list.
585585+586586+ This function throws an error if the list is empty.
587587+588588+ Type: last :: [a] -> a
506589507590 Example:
508591 last [ 1 2 3 ]
···512595 assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
513596 elemAt list (length list - 1);
514597515515- /* Return all elements but the last
598598+ /* Return all elements but the last.
599599+600600+ This function throws an error if the list is empty.
601601+602602+ Type: init :: [a] -> [a]
516603517604 Example:
518605 init [ 1 2 3 ]
···523610 take (length list - 1) list;
524611525612526526- /* return the image of the cross product of some lists by a function
613613+ /* Return the image of the cross product of some lists by a function.
527614528615 Example:
529616 crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
···534621535622 /* Remove duplicate elements from the list. O(n^2) complexity.
536623624624+ Type: unique :: [a] -> [a]
625625+537626 Example:
538538-539627 unique [ 3 2 3 4 ]
540628 => [ 3 2 4 ]
541629 */