aboutsummaryrefslogtreecommitdiff
path: root/lib/lists.nix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2018-10-27 19:23:06 +0200
committerVincent Ambo <mail@tazj.in>2018-10-29 10:42:43 +0100
commit65f50a9bb01a6e2041db1a4e41449e8ea0436adc (patch)
treeb3889ede738a78741e3f1a93d27bf5c41bf64f3b /lib/lists.nix
parent0560caa57893a3c8dd11aeece110672c720c9496 (diff)
lib/lists: Update documentation comments for doc generation
Updates documentation comments with extra information for nixdoc[1] compatibility. [1]: https://github.com/tazjin/nixdoc
Diffstat (limited to 'lib/lists.nix')
-rw-r--r--lib/lists.nix184
1 files changed, 136 insertions, 48 deletions
diff --git a/lib/lists.nix b/lib/lists.nix
index 9ecd8f22003..be541427c24 100644
--- a/lib/lists.nix
+++ b/lib/lists.nix
@@ -1,4 +1,5 @@
# General list operations.
+
{ lib }:
with lib.trivial;
let
@@ -8,21 +9,23 @@ rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
- /* Create a list consisting of a single element. `singleton x' is
- sometimes more convenient with respect to indentation than `[x]'
+ /* Create a list consisting of a single element. `singleton x` is
+ sometimes more convenient with respect to indentation than `[x]`
when x spans multiple lines.
+ Type: singleton :: a -> [a]
+
Example:
singleton "foo"
=> [ "foo" ]
*/
singleton = x: [x];
- /* “right fold” a binary function `op' between successive elements of
- `list' with `nul' as the starting value, i.e.,
- `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'.
- Type:
- foldr :: (a -> b -> b) -> b -> [a] -> b
+ /* “right fold” a binary function `op` between successive elements of
+ `list` with `nul' as the starting value, i.e.,
+ `foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.
+
+ Type: foldr :: (a -> b -> b) -> b -> [a] -> b
Example:
concat = foldr (a: b: a + b) "z"
@@ -42,16 +45,15 @@ rec {
else op (elemAt list n) (fold' (n + 1));
in fold' 0;
- /* `fold' is an alias of `foldr' for historic reasons */
+ /* `fold` is an alias of `foldr` for historic reasons */
# FIXME(Profpatsch): deprecate?
fold = foldr;
- /* “left fold”, like `foldr', but from the left:
+ /* “left fold”, like `foldr`, but from the left:
`foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
- Type:
- foldl :: (b -> a -> b) -> b -> [a] -> b
+ Type: foldl :: (b -> a -> b) -> b -> [a] -> b
Example:
lconcat = foldl (a: b: a + b) "z"
@@ -70,16 +72,20 @@ rec {
else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1);
- /* Strict version of `foldl'.
+ /* Strict version of `foldl`.
The difference is that evaluation is forced upon access. Usually used
with small whole results (in contract with lazily-generated list or large
lists where only a part is consumed.)
+
+ Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
*/
foldl' = builtins.foldl' or foldl;
/* Map with index starting from 0
+ Type: imap0 :: (int -> a -> b) -> [a] -> [b]
+
Example:
imap0 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-0" "b-1" ]
@@ -88,6 +94,8 @@ rec {
/* Map with index starting from 1
+ Type: imap1 :: (int -> a -> b) -> [a] -> [b]
+
Example:
imap1 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-1" "b-2" ]
@@ -96,6 +104,8 @@ rec {
/* Map and concatenate the result.
+ Type: concatMap :: (a -> [b]) -> [a] -> [b]
+
Example:
concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ]
@@ -118,15 +128,21 @@ rec {
/* Remove elements equal to 'e' from a list. Useful for buildInputs.
+ Type: remove :: a -> [a] -> [a]
+
Example:
remove 3 [ 1 3 4 3 ]
=> [ 1 4 ]
*/
- remove = e: filter (x: x != e);
+ remove =
+ # Element to remove from the list
+ e: filter (x: x != e);
/* Find the sole element in the list matching the specified
- predicate, returns `default' if no such element exists, or
- `multiple' if there are multiple matching elements.
+ predicate, returns `default` if no such element exists, or
+ `multiple` if there are multiple matching elements.
+
+ Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a
Example:
findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
@@ -136,14 +152,24 @@ rec {
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
=> "none"
*/
- findSingle = pred: default: multiple: list:
+ findSingle =
+ # Predicate
+ pred:
+ # Default value to return if element was not found.
+ default:
+ # Default value to return if more than one element was found
+ multiple:
+ # Input list
+ list:
let found = filter pred list; len = length found;
in if len == 0 then default
else if len != 1 then multiple
else head found;
/* Find the first element in the list matching the specified
- predicate or returns `default' if no such element exists.
+ predicate or return `default` if no such element exists.
+
+ Type: findFirst :: (a -> bool) -> a -> [a] -> a
Example:
findFirst (x: x > 3) 7 [ 1 6 4 ]
@@ -151,12 +177,20 @@ rec {
findFirst (x: x > 9) 7 [ 1 6 4 ]
=> 7
*/
- findFirst = pred: default: list:
+ findFirst =
+ # Predicate
+ pred:
+ # Default value to return
+ default:
+ # Input list
+ list:
let found = filter pred list;
in if found == [] then default else head found;
- /* Return true iff function `pred' returns true for at least element
- of `list'.
+ /* Return true if function `pred` returns true for at least one
+ element of `list`.
+
+ Type: any :: (a -> bool) -> [a] -> bool
Example:
any isString [ 1 "a" { } ]
@@ -166,8 +200,10 @@ rec {
*/
any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false);
- /* Return true iff function `pred' returns true for all elements of
- `list'.
+ /* Return true if function `pred` returns true for all elements of
+ `list`.
+
+ Type: all :: (a -> bool) -> [a] -> bool
Example:
all (x: x < 3) [ 1 2 ]
@@ -177,19 +213,25 @@ rec {
*/
all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true);
- /* Count how many times function `pred' returns true for the elements
- of `list'.
+ /* Count how many elements of `list` match the supplied predicate
+ function.
+
+ Type: count :: (a -> bool) -> [a] -> int
Example:
count (x: x == 3) [ 3 2 3 4 6 ]
=> 2
*/
- count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
+ count =
+ # Predicate
+ pred: foldl' (c: x: if pred x then c + 1 else c) 0;
/* Return a singleton list or an empty list, depending on a boolean
value. Useful when building lists with optional elements
(e.g. `++ optional (system == "i686-linux") flashplayer').
+ Type: optional :: bool -> a -> [a]
+
Example:
optional true "foo"
=> [ "foo" ]
@@ -200,13 +242,19 @@ rec {
/* Return a list or an empty list, depending on a boolean value.
+ Type: optionals :: bool -> [a] -> [a]
+
Example:
optionals true [ 2 3 ]
=> [ 2 3 ]
optionals false [ 2 3 ]
=> [ ]
*/
- optionals = cond: elems: if cond then elems else [];
+ optionals =
+ # Condition
+ cond:
+ # List to return if condition is true
+ elems: if cond then elems else [];
/* If argument is a list, return it; else, wrap it in a singleton
@@ -223,20 +271,28 @@ rec {
/* Return a list of integers from `first' up to and including `last'.
+ Type: range :: int -> int -> [int]
+
Example:
range 2 4
=> [ 2 3 4 ]
range 3 2
=> [ ]
*/
- range = first: last:
+ range =
+ # First integer in the range
+ first:
+ # Last integer in the range
+ last:
if first > last then
[]
else
genList (n: first + n) (last - first + 1);
- /* Splits the elements of a list in two lists, `right' and
- `wrong', depending on the evaluation of a predicate.
+ /* Splits the elements of a list in two lists, `right` and
+ `wrong`, depending on the evaluation of a predicate.
+
+ Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
Example:
partition (x: x > 2) [ 5 1 2 3 4 ]
@@ -252,7 +308,7 @@ rec {
/* Splits the elements of a list into many lists, using the return value of a predicate.
Predicate should return a string which becomes keys of attrset `groupBy' returns.
- `groupBy'' allows to customise the combining function and initial value
+ `groupBy'` allows to customise the combining function and initial value
Example:
groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
@@ -268,10 +324,6 @@ rec {
xfce = [ { name = "xfce"; script = "xfce4-session &"; } ];
}
-
- groupBy' allows to customise the combining function and initial value
-
- Example:
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; }
*/
@@ -289,17 +341,27 @@ rec {
the merging stops at the shortest. How both lists are merged is defined
by the first argument.
+ Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+
Example:
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
=> ["he" "lo"]
*/
- zipListsWith = f: fst: snd:
+ zipListsWith =
+ # Function to zip elements of both lists
+ f:
+ # First list
+ fst:
+ # Second list
+ snd:
genList
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest.
+ Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
+
Example:
zipLists [ 1 2 ] [ "a" "b" ]
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
@@ -308,6 +370,8 @@ rec {
/* Reverse the order of the elements of a list.
+ Type: reverseList :: [a] -> [a]
+
Example:
reverseList [ "b" "o" "j" ]
@@ -321,8 +385,7 @@ rec {
`before a b == true` means that `b` depends on `a` (there's an
edge from `b` to `a`).
- Examples:
-
+ Example:
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
== { minimal = "/"; # minimal element
visited = [ "/home/user" ]; # seen elements (in reverse order)
@@ -336,7 +399,6 @@ rec {
rest = [ "/home" "other" ]; # everything else
*/
-
listDfs = stopOnCycles: before: list:
let
dfs' = us: visited: rest:
@@ -361,7 +423,7 @@ rec {
`before a b == true` means that `b` should be after `a`
in the result.
- Examples:
+ Example:
toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
== { result = [ "/" "/home" "/home/user" "other" ]; }
@@ -376,7 +438,6 @@ rec {
toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
*/
-
toposort = before: list:
let
dfsthis = listDfs true before list;
@@ -467,26 +528,38 @@ rec {
/* Return the first (at most) N elements of a list.
+ Type: take :: int -> [a] -> [a]
+
Example:
take 2 [ "a" "b" "c" "d" ]
=> [ "a" "b" ]
take 2 [ ]
=> [ ]
*/
- take = count: sublist 0 count;
+ take =
+ # Number of elements to take
+ count: sublist 0 count;
/* Remove the first (at most) N elements of a list.
+ Type: drop :: int -> [a] -> [a]
+
Example:
drop 2 [ "a" "b" "c" "d" ]
=> [ "c" "d" ]
drop 2 [ ]
=> [ ]
*/
- drop = count: list: sublist count (length list) list;
+ drop =
+ # Number of elements to drop
+ count:
+ # Input list
+ list: sublist count (length list) list;
+
+ /* Return a list consisting of at most `count` elements of `list`,
+ starting at index `start`.
- /* Return a list consisting of at most ‘count’ elements of ‘list’,
- starting at index ‘start’.
+ Type: sublist :: int -> int -> [a] -> [a]
Example:
sublist 1 3 [ "a" "b" "c" "d" "e" ]
@@ -494,7 +567,13 @@ rec {
sublist 1 3 [ ]
=> [ ]
*/
- sublist = start: count: list:
+ sublist =
+ # Index at which to start the sublist
+ start:
+ # Number of elements to take
+ count:
+ # Input list
+ list:
let len = length list; in
genList
(n: elemAt list (n + start))
@@ -504,6 +583,10 @@ rec {
/* Return the last element of a list.
+ This function throws an error if the list is empty.
+
+ Type: last :: [a] -> a
+
Example:
last [ 1 2 3 ]
=> 3
@@ -512,7 +595,11 @@ rec {
assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
elemAt list (length list - 1);
- /* Return all elements but the last
+ /* Return all elements but the last.
+
+ This function throws an error if the list is empty.
+
+ Type: init :: [a] -> [a]
Example:
init [ 1 2 3 ]
@@ -523,7 +610,7 @@ rec {
take (length list - 1) list;
- /* return the image of the cross product of some lists by a function
+ /* Return the image of the cross product of some lists by a function.
Example:
crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
@@ -534,8 +621,9 @@ rec {
/* Remove duplicate elements from the list. O(n^2) complexity.
- Example:
+ Type: unique :: [a] -> [a]
+ Example:
unique [ 3 2 3 4 ]
=> [ 3 2 4 ]
*/