Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

lib/lists: Update documentation comments for doc generation

Updates documentation comments with extra information for nixdoc[1]
compatibility.

[1]: https://github.com/tazjin/nixdoc

+136 -48
+136 -48
lib/lists.nix
··· 1 # General list operations. 2 { lib }: 3 with lib.trivial; 4 let ··· 8 9 inherit (builtins) head tail length isList elemAt concatLists filter elem genList; 10 11 - /* Create a list consisting of a single element. `singleton x' is 12 - sometimes more convenient with respect to indentation than `[x]' 13 when x spans multiple lines. 14 15 Example: 16 singleton "foo" 17 => [ "foo" ] 18 */ 19 singleton = x: [x]; 20 21 - /* “right fold” a binary function `op' between successive elements of 22 - `list' with `nul' as the starting value, i.e., 23 - `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. 24 - Type: 25 - foldr :: (a -> b -> b) -> b -> [a] -> b 26 27 Example: 28 concat = foldr (a: b: a + b) "z" ··· 42 else op (elemAt list n) (fold' (n + 1)); 43 in fold' 0; 44 45 - /* `fold' is an alias of `foldr' for historic reasons */ 46 # FIXME(Profpatsch): deprecate? 47 fold = foldr; 48 49 50 - /* “left fold”, like `foldr', but from the left: 51 `foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`. 52 53 - Type: 54 - foldl :: (b -> a -> b) -> b -> [a] -> b 55 56 Example: 57 lconcat = foldl (a: b: a + b) "z" ··· 70 else op (foldl' (n - 1)) (elemAt list n); 71 in foldl' (length list - 1); 72 73 - /* Strict version of `foldl'. 74 75 The difference is that evaluation is forced upon access. Usually used 76 with small whole results (in contract with lazily-generated list or large 77 lists where only a part is consumed.) 78 */ 79 foldl' = builtins.foldl' or foldl; 80 81 /* Map with index starting from 0 82 83 Example: 84 imap0 (i: v: "${v}-${toString i}") ["a" "b"] 85 => [ "a-0" "b-1" ] ··· 87 imap0 = f: list: genList (n: f n (elemAt list n)) (length list); 88 89 /* Map with index starting from 1 90 91 Example: 92 imap1 (i: v: "${v}-${toString i}") ["a" "b"] ··· 95 imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); 96 97 /* Map and concatenate the result. 98 99 Example: 100 concatMap (x: [x] ++ ["z"]) ["a" "b"] ··· 118 119 /* Remove elements equal to 'e' from a list. Useful for buildInputs. 120 121 Example: 122 remove 3 [ 1 3 4 3 ] 123 => [ 1 4 ] 124 */ 125 - remove = e: filter (x: x != e); 126 127 /* Find the sole element in the list matching the specified 128 - predicate, returns `default' if no such element exists, or 129 - `multiple' if there are multiple matching elements. 130 131 Example: 132 findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ] ··· 136 findSingle (x: x == 3) "none" "multiple" [ 1 9 ] 137 => "none" 138 */ 139 - findSingle = pred: default: multiple: list: 140 let found = filter pred list; len = length found; 141 in if len == 0 then default 142 else if len != 1 then multiple 143 else head found; 144 145 /* Find the first element in the list matching the specified 146 - predicate or returns `default' if no such element exists. 147 148 Example: 149 findFirst (x: x > 3) 7 [ 1 6 4 ] ··· 151 findFirst (x: x > 9) 7 [ 1 6 4 ] 152 => 7 153 */ 154 - findFirst = pred: default: list: 155 let found = filter pred list; 156 in if found == [] then default else head found; 157 158 - /* Return true iff function `pred' returns true for at least element 159 - of `list'. 160 161 Example: 162 any isString [ 1 "a" { } ] ··· 166 */ 167 any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false); 168 169 - /* Return true iff function `pred' returns true for all elements of 170 - `list'. 171 172 Example: 173 all (x: x < 3) [ 1 2 ] ··· 177 */ 178 all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true); 179 180 - /* Count how many times function `pred' returns true for the elements 181 - of `list'. 182 183 Example: 184 count (x: x == 3) [ 3 2 3 4 6 ] 185 => 2 186 */ 187 - count = pred: foldl' (c: x: if pred x then c + 1 else c) 0; 188 189 /* Return a singleton list or an empty list, depending on a boolean 190 value. Useful when building lists with optional elements 191 (e.g. `++ optional (system == "i686-linux") flashplayer'). 192 193 Example: 194 optional true "foo" ··· 200 201 /* Return a list or an empty list, depending on a boolean value. 202 203 Example: 204 optionals true [ 2 3 ] 205 => [ 2 3 ] 206 optionals false [ 2 3 ] 207 => [ ] 208 */ 209 - optionals = cond: elems: if cond then elems else []; 210 211 212 /* If argument is a list, return it; else, wrap it in a singleton ··· 223 224 /* Return a list of integers from `first' up to and including `last'. 225 226 Example: 227 range 2 4 228 => [ 2 3 4 ] 229 range 3 2 230 => [ ] 231 */ 232 - range = first: last: 233 if first > last then 234 [] 235 else 236 genList (n: first + n) (last - first + 1); 237 238 - /* Splits the elements of a list in two lists, `right' and 239 - `wrong', depending on the evaluation of a predicate. 240 241 Example: 242 partition (x: x > 2) [ 5 1 2 3 4 ] ··· 252 /* Splits the elements of a list into many lists, using the return value of a predicate. 253 Predicate should return a string which becomes keys of attrset `groupBy' returns. 254 255 - `groupBy'' allows to customise the combining function and initial value 256 257 Example: 258 groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ] ··· 268 xfce = [ { name = "xfce"; script = "xfce4-session &"; } ]; 269 } 270 271 - 272 - groupBy' allows to customise the combining function and initial value 273 - 274 - Example: 275 groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ] 276 => { true = 12; false = 3; } 277 */ ··· 289 the merging stops at the shortest. How both lists are merged is defined 290 by the first argument. 291 292 Example: 293 zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"] 294 => ["he" "lo"] 295 */ 296 - zipListsWith = f: fst: snd: 297 genList 298 (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd)); 299 300 /* Merges two lists of the same size together. If the sizes aren't the same 301 the merging stops at the shortest. 302 303 Example: 304 zipLists [ 1 2 ] [ "a" "b" ] 305 => [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ] ··· 308 309 /* Reverse the order of the elements of a list. 310 311 Example: 312 313 reverseList [ "b" "o" "j" ] ··· 321 `before a b == true` means that `b` depends on `a` (there's an 322 edge from `b` to `a`). 323 324 - Examples: 325 - 326 listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ] 327 == { minimal = "/"; # minimal element 328 visited = [ "/home/user" ]; # seen elements (in reverse order) ··· 336 rest = [ "/home" "other" ]; # everything else 337 338 */ 339 - 340 listDfs = stopOnCycles: before: list: 341 let 342 dfs' = us: visited: rest: ··· 361 `before a b == true` means that `b` should be after `a` 362 in the result. 363 364 - Examples: 365 366 toposort hasPrefix [ "/home/user" "other" "/" "/home" ] 367 == { result = [ "/" "/home" "/home/user" "other" ]; } ··· 376 toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; } 377 378 */ 379 - 380 toposort = before: list: 381 let 382 dfsthis = listDfs true before list; ··· 467 468 /* Return the first (at most) N elements of a list. 469 470 Example: 471 take 2 [ "a" "b" "c" "d" ] 472 => [ "a" "b" ] 473 take 2 [ ] 474 => [ ] 475 */ 476 - take = count: sublist 0 count; 477 478 /* Remove the first (at most) N elements of a list. 479 480 Example: 481 drop 2 [ "a" "b" "c" "d" ] ··· 483 drop 2 [ ] 484 => [ ] 485 */ 486 - drop = count: list: sublist count (length list) list; 487 488 - /* Return a list consisting of at most ‘count’ elements of ‘list’, 489 - starting at index ‘start’. 490 491 Example: 492 sublist 1 3 [ "a" "b" "c" "d" "e" ] ··· 494 sublist 1 3 [ ] 495 => [ ] 496 */ 497 - sublist = start: count: list: 498 let len = length list; in 499 genList 500 (n: elemAt list (n + start)) ··· 503 else count); 504 505 /* Return the last element of a list. 506 507 Example: 508 last [ 1 2 3 ] ··· 512 assert lib.assertMsg (list != []) "lists.last: list must not be empty!"; 513 elemAt list (length list - 1); 514 515 - /* Return all elements but the last 516 517 Example: 518 init [ 1 2 3 ] ··· 523 take (length list - 1) list; 524 525 526 - /* return the image of the cross product of some lists by a function 527 528 Example: 529 crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]] ··· 534 535 /* Remove duplicate elements from the list. O(n^2) complexity. 536 537 Example: 538 - 539 unique [ 3 2 3 4 ] 540 => [ 3 2 4 ] 541 */
··· 1 # General list operations. 2 + 3 { lib }: 4 with lib.trivial; 5 let ··· 9 10 inherit (builtins) head tail length isList elemAt concatLists filter elem genList; 11 12 + /* Create a list consisting of a single element. `singleton x` is 13 + sometimes more convenient with respect to indentation than `[x]` 14 when x spans multiple lines. 15 16 + Type: singleton :: a -> [a] 17 + 18 Example: 19 singleton "foo" 20 => [ "foo" ] 21 */ 22 singleton = x: [x]; 23 24 + /* “right fold” a binary function `op` between successive elements of 25 + `list` with `nul' as the starting value, i.e., 26 + `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`. 27 + 28 + Type: foldr :: (a -> b -> b) -> b -> [a] -> b 29 30 Example: 31 concat = foldr (a: b: a + b) "z" ··· 45 else op (elemAt list n) (fold' (n + 1)); 46 in fold' 0; 47 48 + /* `fold` is an alias of `foldr` for historic reasons */ 49 # FIXME(Profpatsch): deprecate? 50 fold = foldr; 51 52 53 + /* “left fold”, like `foldr`, but from the left: 54 `foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`. 55 56 + Type: foldl :: (b -> a -> b) -> b -> [a] -> b 57 58 Example: 59 lconcat = foldl (a: b: a + b) "z" ··· 72 else op (foldl' (n - 1)) (elemAt list n); 73 in foldl' (length list - 1); 74 75 + /* Strict version of `foldl`. 76 77 The difference is that evaluation is forced upon access. Usually used 78 with small whole results (in contract with lazily-generated list or large 79 lists where only a part is consumed.) 80 + 81 + Type: foldl' :: (b -> a -> b) -> b -> [a] -> b 82 */ 83 foldl' = builtins.foldl' or foldl; 84 85 /* Map with index starting from 0 86 87 + Type: imap0 :: (int -> a -> b) -> [a] -> [b] 88 + 89 Example: 90 imap0 (i: v: "${v}-${toString i}") ["a" "b"] 91 => [ "a-0" "b-1" ] ··· 93 imap0 = f: list: genList (n: f n (elemAt list n)) (length list); 94 95 /* Map with index starting from 1 96 + 97 + Type: imap1 :: (int -> a -> b) -> [a] -> [b] 98 99 Example: 100 imap1 (i: v: "${v}-${toString i}") ["a" "b"] ··· 103 imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); 104 105 /* Map and concatenate the result. 106 + 107 + Type: concatMap :: (a -> [b]) -> [a] -> [b] 108 109 Example: 110 concatMap (x: [x] ++ ["z"]) ["a" "b"] ··· 128 129 /* Remove elements equal to 'e' from a list. Useful for buildInputs. 130 131 + Type: remove :: a -> [a] -> [a] 132 + 133 Example: 134 remove 3 [ 1 3 4 3 ] 135 => [ 1 4 ] 136 */ 137 + remove = 138 + # Element to remove from the list 139 + e: filter (x: x != e); 140 141 /* Find the sole element in the list matching the specified 142 + predicate, returns `default` if no such element exists, or 143 + `multiple` if there are multiple matching elements. 144 + 145 + Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a 146 147 Example: 148 findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ] ··· 152 findSingle (x: x == 3) "none" "multiple" [ 1 9 ] 153 => "none" 154 */ 155 + findSingle = 156 + # Predicate 157 + pred: 158 + # Default value to return if element was not found. 159 + default: 160 + # Default value to return if more than one element was found 161 + multiple: 162 + # Input list 163 + list: 164 let found = filter pred list; len = length found; 165 in if len == 0 then default 166 else if len != 1 then multiple 167 else head found; 168 169 /* Find the first element in the list matching the specified 170 + predicate or return `default` if no such element exists. 171 + 172 + Type: findFirst :: (a -> bool) -> a -> [a] -> a 173 174 Example: 175 findFirst (x: x > 3) 7 [ 1 6 4 ] ··· 177 findFirst (x: x > 9) 7 [ 1 6 4 ] 178 => 7 179 */ 180 + findFirst = 181 + # Predicate 182 + pred: 183 + # Default value to return 184 + default: 185 + # Input list 186 + list: 187 let found = filter pred list; 188 in if found == [] then default else head found; 189 190 + /* Return true if function `pred` returns true for at least one 191 + element of `list`. 192 + 193 + Type: any :: (a -> bool) -> [a] -> bool 194 195 Example: 196 any isString [ 1 "a" { } ] ··· 200 */ 201 any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false); 202 203 + /* Return true if function `pred` returns true for all elements of 204 + `list`. 205 + 206 + Type: all :: (a -> bool) -> [a] -> bool 207 208 Example: 209 all (x: x < 3) [ 1 2 ] ··· 213 */ 214 all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true); 215 216 + /* Count how many elements of `list` match the supplied predicate 217 + function. 218 + 219 + Type: count :: (a -> bool) -> [a] -> int 220 221 Example: 222 count (x: x == 3) [ 3 2 3 4 6 ] 223 => 2 224 */ 225 + count = 226 + # Predicate 227 + pred: foldl' (c: x: if pred x then c + 1 else c) 0; 228 229 /* Return a singleton list or an empty list, depending on a boolean 230 value. Useful when building lists with optional elements 231 (e.g. `++ optional (system == "i686-linux") flashplayer'). 232 + 233 + Type: optional :: bool -> a -> [a] 234 235 Example: 236 optional true "foo" ··· 242 243 /* Return a list or an empty list, depending on a boolean value. 244 245 + Type: optionals :: bool -> [a] -> [a] 246 + 247 Example: 248 optionals true [ 2 3 ] 249 => [ 2 3 ] 250 optionals false [ 2 3 ] 251 => [ ] 252 */ 253 + optionals = 254 + # Condition 255 + cond: 256 + # List to return if condition is true 257 + elems: if cond then elems else []; 258 259 260 /* If argument is a list, return it; else, wrap it in a singleton ··· 271 272 /* Return a list of integers from `first' up to and including `last'. 273 274 + Type: range :: int -> int -> [int] 275 + 276 Example: 277 range 2 4 278 => [ 2 3 4 ] 279 range 3 2 280 => [ ] 281 */ 282 + range = 283 + # First integer in the range 284 + first: 285 + # Last integer in the range 286 + last: 287 if first > last then 288 [] 289 else 290 genList (n: first + n) (last - first + 1); 291 292 + /* Splits the elements of a list in two lists, `right` and 293 + `wrong`, depending on the evaluation of a predicate. 294 + 295 + Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] } 296 297 Example: 298 partition (x: x > 2) [ 5 1 2 3 4 ] ··· 308 /* Splits the elements of a list into many lists, using the return value of a predicate. 309 Predicate should return a string which becomes keys of attrset `groupBy' returns. 310 311 + `groupBy'` allows to customise the combining function and initial value 312 313 Example: 314 groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ] ··· 324 xfce = [ { name = "xfce"; script = "xfce4-session &"; } ]; 325 } 326 327 groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ] 328 => { true = 12; false = 3; } 329 */ ··· 341 the merging stops at the shortest. How both lists are merged is defined 342 by the first argument. 343 344 + Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c] 345 + 346 Example: 347 zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"] 348 => ["he" "lo"] 349 */ 350 + zipListsWith = 351 + # Function to zip elements of both lists 352 + f: 353 + # First list 354 + fst: 355 + # Second list 356 + snd: 357 genList 358 (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd)); 359 360 /* Merges two lists of the same size together. If the sizes aren't the same 361 the merging stops at the shortest. 362 363 + Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}] 364 + 365 Example: 366 zipLists [ 1 2 ] [ "a" "b" ] 367 => [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ] ··· 370 371 /* Reverse the order of the elements of a list. 372 373 + Type: reverseList :: [a] -> [a] 374 + 375 Example: 376 377 reverseList [ "b" "o" "j" ] ··· 385 `before a b == true` means that `b` depends on `a` (there's an 386 edge from `b` to `a`). 387 388 + Example: 389 listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ] 390 == { minimal = "/"; # minimal element 391 visited = [ "/home/user" ]; # seen elements (in reverse order) ··· 399 rest = [ "/home" "other" ]; # everything else 400 401 */ 402 listDfs = stopOnCycles: before: list: 403 let 404 dfs' = us: visited: rest: ··· 423 `before a b == true` means that `b` should be after `a` 424 in the result. 425 426 + Example: 427 428 toposort hasPrefix [ "/home/user" "other" "/" "/home" ] 429 == { result = [ "/" "/home" "/home/user" "other" ]; } ··· 438 toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; } 439 440 */ 441 toposort = before: list: 442 let 443 dfsthis = listDfs true before list; ··· 528 529 /* Return the first (at most) N elements of a list. 530 531 + Type: take :: int -> [a] -> [a] 532 + 533 Example: 534 take 2 [ "a" "b" "c" "d" ] 535 => [ "a" "b" ] 536 take 2 [ ] 537 => [ ] 538 */ 539 + take = 540 + # Number of elements to take 541 + count: sublist 0 count; 542 543 /* Remove the first (at most) N elements of a list. 544 + 545 + Type: drop :: int -> [a] -> [a] 546 547 Example: 548 drop 2 [ "a" "b" "c" "d" ] ··· 550 drop 2 [ ] 551 => [ ] 552 */ 553 + drop = 554 + # Number of elements to drop 555 + count: 556 + # Input list 557 + list: sublist count (length list) list; 558 559 + /* Return a list consisting of at most `count` elements of `list`, 560 + starting at index `start`. 561 + 562 + Type: sublist :: int -> int -> [a] -> [a] 563 564 Example: 565 sublist 1 3 [ "a" "b" "c" "d" "e" ] ··· 567 sublist 1 3 [ ] 568 => [ ] 569 */ 570 + sublist = 571 + # Index at which to start the sublist 572 + start: 573 + # Number of elements to take 574 + count: 575 + # Input list 576 + list: 577 let len = length list; in 578 genList 579 (n: elemAt list (n + start)) ··· 582 else count); 583 584 /* Return the last element of a list. 585 + 586 + This function throws an error if the list is empty. 587 + 588 + Type: last :: [a] -> a 589 590 Example: 591 last [ 1 2 3 ] ··· 595 assert lib.assertMsg (list != []) "lists.last: list must not be empty!"; 596 elemAt list (length list - 1); 597 598 + /* Return all elements but the last. 599 + 600 + This function throws an error if the list is empty. 601 + 602 + Type: init :: [a] -> [a] 603 604 Example: 605 init [ 1 2 3 ] ··· 610 take (length list - 1) list; 611 612 613 + /* Return the image of the cross product of some lists by a function. 614 615 Example: 616 crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]] ··· 621 622 /* Remove duplicate elements from the list. O(n^2) complexity. 623 624 + Type: unique :: [a] -> [a] 625 + 626 Example: 627 unique [ 3 2 3 4 ] 628 => [ 3 2 4 ] 629 */