lib/lists: Update documentation comments for doc generation

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

[1]: https://github.com/tazjin/nixdoc
This commit is contained in:
Vincent Ambo 2018-10-27 19:23:06 +02:00
parent 0560caa578
commit 65f50a9bb0

View File

@ -1,4 +1,5 @@
# General list operations. # General list operations.
{ lib }: { lib }:
with lib.trivial; with lib.trivial;
let let
@ -8,21 +9,23 @@ rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList; inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
/* Create a list consisting of a single element. `singleton x' is /* Create a list consisting of a single element. `singleton x` is
sometimes more convenient with respect to indentation than `[x]' sometimes more convenient with respect to indentation than `[x]`
when x spans multiple lines. when x spans multiple lines.
Type: singleton :: a -> [a]
Example: Example:
singleton "foo" singleton "foo"
=> [ "foo" ] => [ "foo" ]
*/ */
singleton = x: [x]; singleton = x: [x];
/* right fold a binary function `op' between successive elements of /* right fold a binary function `op` between successive elements of
`list' with `nul' as the starting value, i.e., `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))'. `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 Type: foldr :: (a -> b -> b) -> b -> [a] -> b
Example: Example:
concat = foldr (a: b: a + b) "z" concat = foldr (a: b: a + b) "z"
@ -42,16 +45,15 @@ rec {
else op (elemAt list n) (fold' (n + 1)); else op (elemAt list n) (fold' (n + 1));
in fold' 0; in fold' 0;
/* `fold' is an alias of `foldr' for historic reasons */ /* `fold` is an alias of `foldr` for historic reasons */
# FIXME(Profpatsch): deprecate? # FIXME(Profpatsch): deprecate?
fold = foldr; 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)`. `foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
Type: Type: foldl :: (b -> a -> b) -> b -> [a] -> b
foldl :: (b -> a -> b) -> b -> [a] -> b
Example: Example:
lconcat = foldl (a: b: a + b) "z" lconcat = foldl (a: b: a + b) "z"
@ -70,16 +72,20 @@ rec {
else op (foldl' (n - 1)) (elemAt list n); else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1); in foldl' (length list - 1);
/* Strict version of `foldl'. /* Strict version of `foldl`.
The difference is that evaluation is forced upon access. Usually used The difference is that evaluation is forced upon access. Usually used
with small whole results (in contract with lazily-generated list or large with small whole results (in contract with lazily-generated list or large
lists where only a part is consumed.) lists where only a part is consumed.)
Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
*/ */
foldl' = builtins.foldl' or foldl; foldl' = builtins.foldl' or foldl;
/* Map with index starting from 0 /* Map with index starting from 0
Type: imap0 :: (int -> a -> b) -> [a] -> [b]
Example: Example:
imap0 (i: v: "${v}-${toString i}") ["a" "b"] imap0 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-0" "b-1" ] => [ "a-0" "b-1" ]
@ -88,6 +94,8 @@ rec {
/* Map with index starting from 1 /* Map with index starting from 1
Type: imap1 :: (int -> a -> b) -> [a] -> [b]
Example: Example:
imap1 (i: v: "${v}-${toString i}") ["a" "b"] imap1 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-1" "b-2" ] => [ "a-1" "b-2" ]
@ -96,6 +104,8 @@ rec {
/* Map and concatenate the result. /* Map and concatenate the result.
Type: concatMap :: (a -> [b]) -> [a] -> [b]
Example: Example:
concatMap (x: [x] ++ ["z"]) ["a" "b"] concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ] => [ "a" "z" "b" "z" ]
@ -118,15 +128,21 @@ rec {
/* Remove elements equal to 'e' from a list. Useful for buildInputs. /* Remove elements equal to 'e' from a list. Useful for buildInputs.
Type: remove :: a -> [a] -> [a]
Example: Example:
remove 3 [ 1 3 4 3 ] remove 3 [ 1 3 4 3 ]
=> [ 1 4 ] => [ 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 /* Find the sole element in the list matching the specified
predicate, returns `default' if no such element exists, or predicate, returns `default` if no such element exists, or
`multiple' if there are multiple matching elements. `multiple` if there are multiple matching elements.
Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a
Example: Example:
findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ] findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
@ -136,14 +152,24 @@ rec {
findSingle (x: x == 3) "none" "multiple" [ 1 9 ] findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
=> "none" => "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; let found = filter pred list; len = length found;
in if len == 0 then default in if len == 0 then default
else if len != 1 then multiple else if len != 1 then multiple
else head found; else head found;
/* Find the first element in the list matching the specified /* 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: Example:
findFirst (x: x > 3) 7 [ 1 6 4 ] findFirst (x: x > 3) 7 [ 1 6 4 ]
@ -151,12 +177,20 @@ rec {
findFirst (x: x > 9) 7 [ 1 6 4 ] findFirst (x: x > 9) 7 [ 1 6 4 ]
=> 7 => 7
*/ */
findFirst = pred: default: list: findFirst =
# Predicate
pred:
# Default value to return
default:
# Input list
list:
let found = filter pred list; let found = filter pred list;
in if found == [] then default else head found; in if found == [] then default else head found;
/* Return true iff function `pred' returns true for at least element /* Return true if function `pred` returns true for at least one
of `list'. element of `list`.
Type: any :: (a -> bool) -> [a] -> bool
Example: Example:
any isString [ 1 "a" { } ] 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); 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 /* Return true if function `pred` returns true for all elements of
`list'. `list`.
Type: all :: (a -> bool) -> [a] -> bool
Example: Example:
all (x: x < 3) [ 1 2 ] 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); 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 /* Count how many elements of `list` match the supplied predicate
of `list'. function.
Type: count :: (a -> bool) -> [a] -> int
Example: Example:
count (x: x == 3) [ 3 2 3 4 6 ] count (x: x == 3) [ 3 2 3 4 6 ]
=> 2 => 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 /* Return a singleton list or an empty list, depending on a boolean
value. Useful when building lists with optional elements value. Useful when building lists with optional elements
(e.g. `++ optional (system == "i686-linux") flashplayer'). (e.g. `++ optional (system == "i686-linux") flashplayer').
Type: optional :: bool -> a -> [a]
Example: Example:
optional true "foo" optional true "foo"
=> [ "foo" ] => [ "foo" ]
@ -200,13 +242,19 @@ rec {
/* Return a list or an empty list, depending on a boolean value. /* Return a list or an empty list, depending on a boolean value.
Type: optionals :: bool -> [a] -> [a]
Example: Example:
optionals true [ 2 3 ] optionals true [ 2 3 ]
=> [ 2 3 ] => [ 2 3 ]
optionals false [ 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 /* 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'. /* Return a list of integers from `first' up to and including `last'.
Type: range :: int -> int -> [int]
Example: Example:
range 2 4 range 2 4
=> [ 2 3 4 ] => [ 2 3 4 ]
range 3 2 range 3 2
=> [ ] => [ ]
*/ */
range = first: last: range =
# First integer in the range
first:
# Last integer in the range
last:
if first > last then if first > last then
[] []
else else
genList (n: first + n) (last - first + 1); genList (n: first + n) (last - first + 1);
/* Splits the elements of a list in two lists, `right' and /* Splits the elements of a list in two lists, `right` and
`wrong', depending on the evaluation of a predicate. `wrong`, depending on the evaluation of a predicate.
Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
Example: Example:
partition (x: x > 2) [ 5 1 2 3 4 ] 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. /* 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. 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: Example:
groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ] groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
@ -268,10 +324,6 @@ rec {
xfce = [ { name = "xfce"; script = "xfce4-session &"; } ]; 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 ] groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; } => { true = 12; false = 3; }
*/ */
@ -289,17 +341,27 @@ rec {
the merging stops at the shortest. How both lists are merged is defined the merging stops at the shortest. How both lists are merged is defined
by the first argument. by the first argument.
Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Example: Example:
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"] zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
=> ["he" "lo"] => ["he" "lo"]
*/ */
zipListsWith = f: fst: snd: zipListsWith =
# Function to zip elements of both lists
f:
# First list
fst:
# Second list
snd:
genList genList
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd)); (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 /* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest. the merging stops at the shortest.
Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
Example: Example:
zipLists [ 1 2 ] [ "a" "b" ] zipLists [ 1 2 ] [ "a" "b" ]
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ] => [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
@ -308,6 +370,8 @@ rec {
/* Reverse the order of the elements of a list. /* Reverse the order of the elements of a list.
Type: reverseList :: [a] -> [a]
Example: Example:
reverseList [ "b" "o" "j" ] reverseList [ "b" "o" "j" ]
@ -321,8 +385,7 @@ rec {
`before a b == true` means that `b` depends on `a` (there's an `before a b == true` means that `b` depends on `a` (there's an
edge from `b` to `a`). edge from `b` to `a`).
Examples: Example:
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ] listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
== { minimal = "/"; # minimal element == { minimal = "/"; # minimal element
visited = [ "/home/user" ]; # seen elements (in reverse order) visited = [ "/home/user" ]; # seen elements (in reverse order)
@ -336,7 +399,6 @@ rec {
rest = [ "/home" "other" ]; # everything else rest = [ "/home" "other" ]; # everything else
*/ */
listDfs = stopOnCycles: before: list: listDfs = stopOnCycles: before: list:
let let
dfs' = us: visited: rest: dfs' = us: visited: rest:
@ -361,7 +423,7 @@ rec {
`before a b == true` means that `b` should be after `a` `before a b == true` means that `b` should be after `a`
in the result. in the result.
Examples: Example:
toposort hasPrefix [ "/home/user" "other" "/" "/home" ] toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
== { result = [ "/" "/home" "/home/user" "other" ]; } == { result = [ "/" "/home" "/home/user" "other" ]; }
@ -376,7 +438,6 @@ rec {
toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; } toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
*/ */
toposort = before: list: toposort = before: list:
let let
dfsthis = listDfs true before list; dfsthis = listDfs true before list;
@ -467,26 +528,38 @@ rec {
/* Return the first (at most) N elements of a list. /* Return the first (at most) N elements of a list.
Type: take :: int -> [a] -> [a]
Example: Example:
take 2 [ "a" "b" "c" "d" ] take 2 [ "a" "b" "c" "d" ]
=> [ "a" "b" ] => [ "a" "b" ]
take 2 [ ] 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. /* Remove the first (at most) N elements of a list.
Type: drop :: int -> [a] -> [a]
Example: Example:
drop 2 [ "a" "b" "c" "d" ] drop 2 [ "a" "b" "c" "d" ]
=> [ "c" "d" ] => [ "c" "d" ]
drop 2 [ ] 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, /* Return a list consisting of at most `count` elements of `list`,
starting at index start. starting at index `start`.
Type: sublist :: int -> int -> [a] -> [a]
Example: Example:
sublist 1 3 [ "a" "b" "c" "d" "e" ] sublist 1 3 [ "a" "b" "c" "d" "e" ]
@ -494,7 +567,13 @@ rec {
sublist 1 3 [ ] 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 let len = length list; in
genList genList
(n: elemAt list (n + start)) (n: elemAt list (n + start))
@ -504,6 +583,10 @@ rec {
/* Return the last element of a list. /* Return the last element of a list.
This function throws an error if the list is empty.
Type: last :: [a] -> a
Example: Example:
last [ 1 2 3 ] last [ 1 2 3 ]
=> 3 => 3
@ -512,7 +595,11 @@ rec {
assert lib.assertMsg (list != []) "lists.last: list must not be empty!"; assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
elemAt list (length list - 1); 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: Example:
init [ 1 2 3 ] init [ 1 2 3 ]
@ -523,7 +610,7 @@ rec {
take (length list - 1) list; 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: Example:
crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]] 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. /* Remove duplicate elements from the list. O(n^2) complexity.
Example: Type: unique :: [a] -> [a]
Example:
unique [ 3 2 3 4 ] unique [ 3 2 3 4 ]
=> [ 3 2 4 ] => [ 3 2 4 ]
*/ */