about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-support/lib-function-docs.nix2
-rw-r--r--doc/functions/library.xml8
-rw-r--r--doc/functions/library/.gitkeep0
-rw-r--r--doc/functions/library/asserts.xml112
-rw-r--r--doc/functions/library/attrsets.xml1751
-rw-r--r--lib/asserts.nix19
-rw-r--r--lib/attrsets.nix453
7 files changed, 385 insertions, 1960 deletions
diff --git a/doc/doc-support/lib-function-docs.nix b/doc/doc-support/lib-function-docs.nix
index cbcbed4310af1..64f5ed56843c0 100644
--- a/doc/doc-support/lib-function-docs.nix
+++ b/doc/doc-support/lib-function-docs.nix
@@ -17,6 +17,8 @@ with pkgs; stdenv.mkDerivation {
     mkdir -p $out
     ln -s ${locationsXml} $out/locations.xml
 
+    docgen asserts 'Assert functions'
+    docgen attrsets 'Attribute-set functions'
     docgen strings 'String manipulation functions'
     docgen trivial 'Miscellaneous functions'
     docgen lists 'List manipulation functions'
diff --git a/doc/functions/library.xml b/doc/functions/library.xml
index b291356c14b85..0a8bae229f261 100644
--- a/doc/functions/library.xml
+++ b/doc/functions/library.xml
@@ -8,14 +8,14 @@
   Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or through <code>import &lt;nixpkgs/lib&gt;</code>.
  </para>
 
- <xi:include href="./library/asserts.xml" />
-
- <xi:include href="./library/attrsets.xml" />
-
 <!-- These docs are generated via nixdoc. To add another generated
       library function file to this list, the file
       `lib-function-docs.nix` must also be updated. -->
 
+ <xi:include href="./library/generated/asserts.xml" />
+
+ <xi:include href="./library/generated/attrsets.xml" />
+
  <xi:include href="./library/generated/strings.xml" />
 
  <xi:include href="./library/generated/trivial.xml" />
diff --git a/doc/functions/library/.gitkeep b/doc/functions/library/.gitkeep
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/doc/functions/library/.gitkeep
diff --git a/doc/functions/library/asserts.xml b/doc/functions/library/asserts.xml
deleted file mode 100644
index 7c94222ef139e..0000000000000
--- a/doc/functions/library/asserts.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<section xmlns="http://docbook.org/ns/docbook"
-         xmlns:xlink="http://www.w3.org/1999/xlink"
-         xmlns:xi="http://www.w3.org/2001/XInclude"
-         xml:id="sec-functions-library-asserts">
- <title>Assert functions</title>
-
- <section xml:id="function-library-lib.asserts.assertMsg">
-  <title><function>lib.asserts.assertMsg</function></title>
-
-  <subtitle><literal>assertMsg :: Bool -> String -> Bool</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.asserts.assertMsg" />
-
-  <para>
-   Print a trace message if <literal>pred</literal> is false.
-  </para>
-
-  <para>
-   Intended to be used to augment asserts with helpful error messages.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>pred</varname>
-    </term>
-    <listitem>
-     <para>
-      Condition under which the <varname>msg</varname> should <emphasis>not</emphasis> be printed.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>msg</varname>
-    </term>
-    <listitem>
-     <para>
-      Message to print.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.asserts.assertMsg-example-false">
-   <title>Printing when the predicate is false</title>
-<programlisting><![CDATA[
-assert lib.asserts.assertMsg ("foo" == "bar") "foo is not bar, silly"
-stderr> trace: foo is not bar, silly
-stderr> assert failed
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.asserts.assertOneOf">
-  <title><function>lib.asserts.assertOneOf</function></title>
-
-  <subtitle><literal>assertOneOf :: String -> String ->
-      StringList -> Bool</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.asserts.assertOneOf" />
-
-  <para>
-   Specialized <function>asserts.assertMsg</function> for checking if <varname>val</varname> is one of the elements of <varname>xs</varname>. Useful for checking enums.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>name</varname>
-    </term>
-    <listitem>
-     <para>
-      The name of the variable the user entered <varname>val</varname> into, for inclusion in the error message.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>val</varname>
-    </term>
-    <listitem>
-     <para>
-      The value of what the user provided, to be compared against the values in <varname>xs</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>xs</varname>
-    </term>
-    <listitem>
-     <para>
-      The list of valid values.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.asserts.assertOneOf-example">
-   <title>Ensuring a user provided a possible value</title>
-<programlisting><![CDATA[
-let sslLibrary = "bearssl";
-in lib.asserts.assertOneOf "sslLibrary" sslLibrary [ "openssl" "libressl" ];
-=> false
-stderr> trace: sslLibrary must be one of "openssl", "libressl", but is: "bearssl"
-        ]]></programlisting>
-  </example>
- </section>
-</section>
diff --git a/doc/functions/library/attrsets.xml b/doc/functions/library/attrsets.xml
deleted file mode 100644
index 052bfa1f6ae34..0000000000000
--- a/doc/functions/library/attrsets.xml
+++ /dev/null
@@ -1,1751 +0,0 @@
-<section xmlns="http://docbook.org/ns/docbook"
-         xmlns:xlink="http://www.w3.org/1999/xlink"
-         xmlns:xi="http://www.w3.org/2001/XInclude"
-         xml:id="sec-functions-library-attrset">
- <title>Attribute-Set Functions</title>
-
- <section xml:id="function-library-lib.attrsets.attrByPath">
-  <title><function>lib.attrset.attrByPath</function></title>
-
-  <subtitle><literal>attrByPath :: [String] -> Any -> AttrSet -> Any</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.attrByPath" />
-
-  <para>
-   Return an attribute from within nested attribute sets.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrPath</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of strings representing the path through the nested attribute set <varname>set</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>default</varname>
-    </term>
-    <listitem>
-     <para>
-      Default value if <varname>attrPath</varname> does not resolve to an existing value.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The nested attributeset to select values from.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrset.attrByPath-example-value-exists">
-   <title>Extracting a value from a nested attribute set</title>
-<programlisting><![CDATA[
-let set = { a = { b = 3; }; };
-in lib.attrsets.attrByPath [ "a" "b" ] 0 set
-=> 3
-]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrset.attrByPath-example-default-value">
-   <title>No value at the path, instead using the default</title>
-<programlisting><![CDATA[
-lib.attrsets.attrByPath [ "a" "b" ] 0 {}
-=> 0
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.hasAttrByPath">
-  <title><function>lib.attrsets.hasAttrByPath</function></title>
-
-  <subtitle><literal>hasAttrByPath :: [String] -> AttrSet -> Bool</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.hasAttrByPath" />
-
-  <para>
-   Determine if an attribute exists within a nested attribute set.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrPath</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of strings representing the path through the nested attribute set <varname>set</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The nested attributeset to check.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.hasAttrByPath-example">
-   <title>A nested value does exist inside a set</title>
-<programlisting><![CDATA[
-lib.attrsets.hasAttrByPath
-  [ "a" "b" "c" "d" ]
-  { a = { b = { c = { d = 123; }; }; }; }
-=> true
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.setAttrByPath">
-  <title><function>lib.attrsets.setAttrByPath</function></title>
-
-  <subtitle><literal>setAttrByPath :: [String] -> Any -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.setAttrByPath" />
-
-  <para>
-   Create a new attribute set with <varname>value</varname> set at the nested attribute location specified in <varname>attrPath</varname>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrPath</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of strings representing the path through the nested attribute set.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>value</varname>
-    </term>
-    <listitem>
-     <para>
-      The value to set at the location described by <varname>attrPath</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.setAttrByPath-example">
-   <title>Creating a new nested attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.setAttrByPath [ "a" "b" ] 3
-=> { a = { b = 3; }; }
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.getAttrFromPath">
-  <title><function>lib.attrsets.getAttrFromPath</function></title>
-
-  <subtitle><literal>getAttrFromPath :: [String] -> AttrSet -> Value</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.getAttrFromPath" />
-
-  <para>
-   Like <xref linkend="function-library-lib.attrsets.attrByPath" /> except without a default, and it will throw if the value doesn't exist.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrPath</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of strings representing the path through the nested attribute set <varname>set</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The nested attribute set to find the value in.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.getAttrPath-example-success">
-   <title>Succesfully getting a value from an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.getAttrFromPath [ "a" "b" ] { a = { b = 3; }; }
-=> 3
-]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrsets.getAttrPath-example-throw">
-   <title>Throwing after failing to get a value from an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.getAttrFromPath [ "x" "y" ] { }
-=> error: cannot find attribute `x.y'
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.attrVals">
-  <title><function>lib.attrsets.attrVals</function></title>
-
-  <subtitle><literal>attrVals :: [String] -> AttrSet -> [Any]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.attrVals" />
-
-  <para>
-   Return the specified attributes from a set. All values must exist.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>nameList</varname>
-    </term>
-    <listitem>
-     <para>
-      The list of attributes to fetch from <varname>set</varname>. Each attribute name must exist on the attrbitue set.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The set to get attribute values from.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.attrVals-example-success">
-   <title>Getting several values from an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.attrVals [ "a" "b" "c" ] { a = 1; b = 2; c = 3; }
-=> [ 1 2 3 ]
-]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrsets.attrVals-failure">
-   <title>Getting missing values from an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.attrVals [ "d" ] { }
-error: attribute 'd' missing
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.attrValues">
-  <title><function>lib.attrsets.attrValues</function></title>
-
-  <subtitle><literal>attrValues :: AttrSet -> [Any]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.attrValues" />
-
-  <para>
-   Get all the attribute values from an attribute set.
-  </para>
-
-  <para>
-   Provides a backwards-compatible interface of <function>builtins.attrValues</function> for Nix version older than 1.8.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrs</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.attrValues-example">
-   <title></title>
-<programlisting><![CDATA[
-lib.attrsets.attrValues { a = 1; b = 2; c = 3; }
-=> [ 1 2 3 ]
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.catAttrs">
-  <title><function>lib.attrsets.catAttrs</function></title>
-
-  <subtitle><literal>catAttrs :: String -> [AttrSet] -> [Any]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.catAttrs" />
-
-  <para>
-   Collect each attribute named `attr' from the list of attribute sets, <varname>sets</varname>. Sets that don't contain the named attribute are ignored.
-  </para>
-
-  <para>
-   Provides a backwards-compatible interface of <function>builtins.catAttrs</function> for Nix version older than 1.9.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attr</varname>
-    </term>
-    <listitem>
-     <para>
-      Attribute name to select from each attribute set in <varname>sets</varname>.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>sets</varname>
-    </term>
-    <listitem>
-     <para>
-      The list of attribute sets to select <varname>attr</varname> from.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.catAttrs-example">
-   <title>Collect an attribute from a list of attribute sets.</title>
-   <para>
-    Attribute sets which don't have the attribute are ignored.
-   </para>
-<programlisting><![CDATA[
-catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
-=> [ 1 2 ]
-      ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.filterAttrs">
-  <title><function>lib.attrsets.filterAttrs</function></title>
-
-  <subtitle><literal>filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.filterAttrs" />
-
-  <para>
-   Filter an attribute set by removing all attributes for which the given predicate return false.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>pred</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any -> Bool</literal>
-     </para>
-     <para>
-      Predicate which returns true to include an attribute, or returns false to exclude it.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's name
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-     <para>
-      Returns <literal>true</literal> to include the attribute, <literal>false</literal> to exclude the attribute.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to filter
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.filterAttrs-example">
-   <title>Filtering an attributeset</title>
-<programlisting><![CDATA[
-filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
-=> { foo = 1; }
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.filterAttrsRecursive">
-  <title><function>lib.attrsets.filterAttrsRecursive</function></title>
-
-  <subtitle><literal>filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.filterAttrsRecursive" />
-
-  <para>
-   Filter an attribute set recursively by removing all attributes for which the given predicate return false.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>pred</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any -> Bool</literal>
-     </para>
-     <para>
-      Predicate which returns true to include an attribute, or returns false to exclude it.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's name
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-     <para>
-      Returns <literal>true</literal> to include the attribute, <literal>false</literal> to exclude the attribute.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to filter
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.filterAttrsRecursive-example">
-   <title>Recursively filtering an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.filterAttrsRecursive
-  (n: v: v != null)
-  {
-    levelA = {
-      example = "hi";
-      levelB = {
-        hello = "there";
-        this-one-is-present = {
-          this-is-excluded = null;
-        };
-      };
-      this-one-is-also-excluded = null;
-    };
-    also-excluded = null;
-  }
-=> {
-     levelA = {
-       example = "hi";
-       levelB = {
-         hello = "there";
-         this-one-is-present = { };
-       };
-     };
-   }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.foldAttrs">
-  <title><function>lib.attrsets.foldAttrs</function></title>
-
-  <subtitle><literal>foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.foldAttrs" />
-
-  <para>
-   Apply fold function to values grouped by key.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>op</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>Any -> Any -> Any</literal>
-     </para>
-     <para>
-      Given a value <varname>val</varname> and a collector <varname>col</varname>, combine the two.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>val</varname>
-       </term>
-       <listitem>
-        <para>
-         An attribute's value
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>col</varname>
-       </term>
-       <listitem>
-<!-- TODO: make this not bad, use more fold-ey terms -->
-        <para>
-         The result of previous <function>op</function> calls with other values and <function>nul</function>.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>nul</varname>
-    </term>
-    <listitem>
-     <para>
-      The null-value, the starting value.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>list_of_attrs</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of attribute sets to fold together by key.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.foldAttrs-example">
-   <title>Combining an attribute of lists in to one attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.foldAttrs
-  (n: a: [n] ++ a) []
-  [
-    { a = 2; b = 7; }
-    { a = 3; }
-    { b = 6; }
-  ]
-=> { a = [ 2 3 ]; b = [ 7 6 ]; }
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.collect">
-  <title><function>lib.attrsets.collect</function></title>
-
-  <subtitle><literal>collect :: (Any -> Bool) -> AttrSet -> [Any]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.collect" />
-
-  <para>
-   Recursively collect sets that verify a given predicate named <varname>pred</varname> from the set <varname>attrs</varname>. The recursion stops when <varname>pred</varname> returns <literal>true</literal>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>pred</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>Any -> Bool</literal>
-     </para>
-     <para>
-      Given an attribute's value, determine if recursion should stop.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute set value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>attrs</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to recursively collect.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.collect-example-lists">
-   <title>Collecting all lists from an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.collect isList { a = { b = ["b"]; }; c = [1]; }
-=> [["b"] [1]]
-]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrsets.collect-example-outpath">
-   <title>Collecting all attribute-sets which contain the <literal>outPath</literal> attribute name.</title>
-<programlisting><![CDATA[
-collect (x: x ? outPath)
-  { a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
-=> [{ outPath = "a/"; } { outPath = "b/"; }]
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.nameValuePair">
-  <title><function>lib.attrsets.nameValuePair</function></title>
-
-  <subtitle><literal>nameValuePair :: String -> Any -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.nameValuePair" />
-
-  <para>
-   Utility function that creates a <literal>{name, value}</literal> pair as expected by <function>builtins.listToAttrs</function>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>name</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute name.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>value</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute value.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.nameValuePair-example">
-   <title>Creating a name value pair</title>
-<programlisting><![CDATA[
-nameValuePair "some" 6
-=> { name = "some"; value = 6; }
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.mapAttrs">
-  <title><function>lib.attrsets.mapAttrs</function></title>
-
-  <subtitle><literal></literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrs" />
-
-  <para>
-   Apply a function to each element in an attribute set, creating a new attribute set.
-  </para>
-
-  <para>
-   Provides a backwards-compatible interface of <function>builtins.mapAttrs</function> for Nix version older than 2.1.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>fn</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any -> Any</literal>
-     </para>
-     <para>
-      Given an attribute's name and value, return a new value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.mapAttrs-example">
-   <title>Modifying each value of an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.mapAttrs
-  (name: value: name + "-" + value)
-  { x = "foo"; y = "bar"; }
-=> { x = "x-foo"; y = "y-bar"; }
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.mapAttrs-prime">
-  <title><function>lib.attrsets.mapAttrs&apos;</function></title>
-
-  <subtitle><literal>mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrs-prime" />
-
-  <para>
-   Like <function>mapAttrs</function>, but allows the name of each attribute to be changed in addition to the value. The applied function should return both the new name and value as a <function>nameValuePair</function>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>fn</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any -> { name = String; value = Any }</literal>
-     </para>
-     <para>
-      Given an attribute's name and value, return a new <link
-       linkend="function-library-lib.attrsets.nameValuePair">name value pair</link>.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to map over.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.mapAttrs-prime-example">
-   <title>Change the name and value of each attribute of an attribute set</title>
-<programlisting><![CDATA[
-lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair ("foo_" + name) ("bar-" + value))
-   { x = "a"; y = "b"; }
-=> { foo_x = "bar-a"; foo_y = "bar-b"; }
-
-    ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.mapAttrsToList">
-  <title><function>lib.attrsets.mapAttrsToList</function></title>
-
-  <subtitle><literal>mapAttrsToList :: (String -> Any -> Any) ->
-   AttrSet -> [Any]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrsToList" />
-
-  <para>
-   Call <varname>fn</varname> for each attribute in the given <varname>set</varname> and return the result in a list.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>fn</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any -> Any</literal>
-     </para>
-     <para>
-      Given an attribute's name and value, return a new value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to map over.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.mapAttrsToList-example">
-   <title>Combine attribute values and names in to a list</title>
-<programlisting><![CDATA[
-lib.attrsets.mapAttrsToList (name: value: "${name}=${value}")
-   { x = "a"; y = "b"; }
-=> [ "x=a" "y=b" ]
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.mapAttrsRecursive">
-  <title><function>lib.attrsets.mapAttrsRecursive</function></title>
-
-  <subtitle><literal>mapAttrsRecursive :: ([String] > Any -> Any) -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrsRecursive" />
-
-  <para>
-   Like <function>mapAttrs</function>, except that it recursively applies itself to attribute sets. Also, the first argument of the argument function is a <emphasis>list</emphasis> of the names of the containing attributes.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>f</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>[ String ] -> Any -> Any</literal>
-     </para>
-     <para>
-      Given a list of attribute names and value, return a new value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name_path</varname>
-       </term>
-       <listitem>
-        <para>
-         The list of attribute names to this value.
-        </para>
-        <para>
-         For example, the <varname>name_path</varname> for the <literal>example</literal> string in the attribute set <literal>{ foo = { bar = "example"; }; }</literal> is <literal>[ "foo" "bar" ]</literal>.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to recursively map over.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.mapAttrsRecursive-example">
-   <title>A contrived example of using <function>lib.attrsets.mapAttrsRecursive</function></title>
-<programlisting><![CDATA[
-mapAttrsRecursive
-  (path: value: concatStringsSep "-" (path ++ [value]))
-  {
-    n = {
-      a = "A";
-      m = {
-        b = "B";
-        c = "C";
-      };
-    };
-    d = "D";
-  }
-=> {
-     n = {
-       a = "n-a-A";
-       m = {
-         b = "n-m-b-B";
-         c = "n-m-c-C";
-       };
-     };
-     d = "d-D";
-   }
-    ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.mapAttrsRecursiveCond">
-  <title><function>lib.attrsets.mapAttrsRecursiveCond</function></title>
-
-  <subtitle><literal>mapAttrsRecursiveCond :: (AttrSet -> Bool) -> ([ String ] -> Any -> Any) -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.mapAttrsRecursiveCond" />
-
-  <para>
-   Like <function>mapAttrsRecursive</function>, but it takes an additional predicate function that tells it whether to recursive into an attribute set. If it returns false, <function>mapAttrsRecursiveCond</function> does not recurse, but does apply the map function. It is returns true, it does recurse, and does not apply the map function.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>cond</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>(AttrSet -> Bool)</literal>
-     </para>
-     <para>
-      Determine if <function>mapAttrsRecursive</function> should recurse deeper in to the attribute set.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>attributeset</varname>
-       </term>
-       <listitem>
-        <para>
-         An attribute set.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>f</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>[ String ] -> Any -> Any</literal>
-     </para>
-     <para>
-      Given a list of attribute names and value, return a new value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name_path</varname>
-       </term>
-       <listitem>
-        <para>
-         The list of attribute names to this value.
-        </para>
-        <para>
-         For example, the <varname>name_path</varname> for the <literal>example</literal> string in the attribute set <literal>{ foo = { bar = "example"; }; }</literal> is <literal>[ "foo" "bar" ]</literal>.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>value</varname>
-       </term>
-       <listitem>
-        <para>
-         The attribute's value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to recursively map over.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.mapAttrsRecursiveCond-example">
-   <title>Only convert attribute values to JSON if the containing attribute set is marked for recursion</title>
-<programlisting><![CDATA[
-lib.attrsets.mapAttrsRecursiveCond
-  ({ recurse ? false, ... }: recurse)
-  (name: value: builtins.toJSON value)
-  {
-    dorecur = {
-      recurse = true;
-      hello = "there";
-    };
-    dontrecur = {
-      converted-to- = "json";
-    };
-  }
-=> {
-     dorecur = {
-       hello = "\"there\"";
-       recurse = "true";
-     };
-     dontrecur = "{\"converted-to\":\"json\"}";
-   }
-    ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.genAttrs">
-  <title><function>lib.attrsets.genAttrs</function></title>
-
-  <subtitle><literal>genAttrs :: [ String ] -> (String -> Any) -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.genAttrs" />
-
-  <para>
-   Generate an attribute set by mapping a function over a list of attribute names.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>names</varname>
-    </term>
-    <listitem>
-     <para>
-      Names of values in the resulting attribute set.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>f</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>String -> Any</literal>
-     </para>
-     <para>
-      Takes the name of the attribute and return the attribute's value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute to generate a value for.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.genAttrs-example">
-   <title>Generate an attrset based on names only</title>
-<programlisting><![CDATA[
-lib.attrsets.genAttrs [ "foo" "bar" ] (name: "x_${name}")
-=> { foo = "x_foo"; bar = "x_bar"; }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.isDerivation">
-  <title><function>lib.attrsets.isDerivation</function></title>
-
-  <subtitle><literal>isDerivation :: Any -> Bool</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.isDerivation" />
-
-  <para>
-   Check whether the argument is a derivation. Any set with <code>{ type = "derivation"; }</code> counts as a derivation.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>value</varname>
-    </term>
-    <listitem>
-     <para>
-      The value which is possibly a derivation.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.isDerivation-example-true">
-   <title>A package is a derivation</title>
-<programlisting><![CDATA[
-lib.attrsets.isDerivation (import <nixpkgs> {}).ruby
-=> true
-     ]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrsets.isDerivation-example-false">
-   <title>Anything else is not a derivation</title>
-<programlisting><![CDATA[
-lib.attrsets.isDerivation "foobar"
-=> false
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.toDerivation">
-  <title><function>lib.attrsets.toDerivation</function></title>
-
-  <subtitle><literal>toDerivation :: Path -> Derivation</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.toDerivation" />
-
-  <para>
-   Converts a store path to a fake derivation.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>path</varname>
-    </term>
-    <listitem>
-     <para>
-      A store path to convert to a derivation.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
- </section>
-
- <section xml:id="function-library-lib.attrsets.optionalAttrs">
-  <title><function>lib.attrsets.optionalAttrs</function></title>
-
-  <subtitle><literal>optionalAttrs :: Bool -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.optionalAttrs" />
-
-  <para>
-   Conditionally return an attribute set or an empty attribute set.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>cond</varname>
-    </term>
-    <listitem>
-     <para>
-      Condition under which the <varname>as</varname> attribute set is returned.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>as</varname>
-    </term>
-    <listitem>
-     <para>
-      The attribute set to return if <varname>cond</varname> is true.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.optionalAttrs-example-true">
-   <title>Return the provided attribute set when <varname>cond</varname> is true</title>
-<programlisting><![CDATA[
-lib.attrsets.optionalAttrs true { my = "set"; }
-=> { my = "set"; }
-     ]]></programlisting>
-  </example>
-
-  <example xml:id="function-library-lib.attrsets.optionalAttrs-example-false">
-   <title>Return an empty attribute set when <varname>cond</varname> is false</title>
-<programlisting><![CDATA[
-lib.attrsets.optionalAttrs false { my = "set"; }
-=> { }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.zipAttrsWithNames">
-  <title><function>lib.attrsets.zipAttrsWithNames</function></title>
-
-  <subtitle><literal>zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.zipAttrsWithNames" />
-
-  <para>
-   Merge sets of attributes and use the function <varname>f</varname> to merge attribute values where the attribute name is in <varname>names</varname>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>names</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of attribute names to zip.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>f</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>(String -> [ Any ] -> Any</literal>
-     </para>
-     <para>
-      Accepts an attribute name, all the values, and returns a combined value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute each value came from.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>vs</varname>
-       </term>
-       <listitem>
-        <para>
-         A list of values collected from the list of attribute sets.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>sets</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of attribute sets to zip together.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.zipAttrsWithNames-example">
-   <title>Summing a list of attribute sets of numbers</title>
-<programlisting><![CDATA[
-lib.attrsets.zipAttrsWithNames
-  [ "a" "b" ]
-  (name: vals: "${name} ${toString (builtins.foldl' (a: b: a + b) 0 vals)}")
-  [
-    { a = 1; b = 1; c = 1; }
-    { a = 10; }
-    { b = 100; }
-    { c = 1000; }
-  ]
-=> { a = "a 11"; b = "b 101"; }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.zipAttrsWith">
-  <title><function>lib.attrsets.zipAttrsWith</function></title>
-
-  <subtitle><literal>zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.zipAttrsWith" />
-
-  <para>
-   Merge sets of attributes and use the function <varname>f</varname> to merge attribute values. Similar to <xref
-   linkend="function-library-lib.attrsets.zipAttrsWithNames" /> where all key names are passed for <varname>names</varname>.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>f</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>(String -> [ Any ] -> Any</literal>
-     </para>
-     <para>
-      Accepts an attribute name, all the values, and returns a combined value.
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>name</varname>
-       </term>
-       <listitem>
-        <para>
-         The name of the attribute each value came from.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>vs</varname>
-       </term>
-       <listitem>
-        <para>
-         A list of values collected from the list of attribute sets.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>sets</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of attribute sets to zip together.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.zipAttrsWith-example">
-   <title>Summing a list of attribute sets of numbers</title>
-<programlisting><![CDATA[
-lib.attrsets.zipAttrsWith
-  (name: vals: "${name} ${toString (builtins.foldl' (a: b: a + b) 0 vals)}")
-  [
-    { a = 1; b = 1; c = 1; }
-    { a = 10; }
-    { b = 100; }
-    { c = 1000; }
-  ]
-=> { a = "a 11"; b = "b 101"; c = "c 1001"; }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.zipAttrs">
-  <title><function>lib.attrsets.zipAttrs</function></title>
-
-  <subtitle><literal>zipAttrs :: [ AttrSet ] -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.zipAttrs" />
-
-  <para>
-   Merge sets of attributes and combine each attribute value in to a list. Similar to <xref linkend="function-library-lib.attrsets.zipAttrsWith" /> where the merge function returns a list of all values.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>sets</varname>
-    </term>
-    <listitem>
-     <para>
-      A list of attribute sets to zip together.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.zipAttrs-example">
-   <title>Combining a list of attribute sets</title>
-<programlisting><![CDATA[
-lib.attrsets.zipAttrs
-  [
-    { a = 1; b = 1; c = 1; }
-    { a = 10; }
-    { b = 100; }
-    { c = 1000; }
-  ]
-=> { a = [ 1 10 ]; b = [ 1 100 ]; c = [ 1 1000 ]; }
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.recursiveUpdateUntil">
-  <title><function>lib.attrsets.recursiveUpdateUntil</function></title>
-
-  <subtitle><literal>recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.recursiveUpdateUntil" />
-
-  <para>
-   Does the same as the update operator <literal>//</literal> except that attributes are merged until the given predicate is verified. The predicate should accept 3 arguments which are the path to reach the attribute, a part of the first attribute set and a part of the second attribute set. When the predicate is verified, the value of the first attribute set is replaced by the value of the second attribute set.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>pred</varname>
-    </term>
-    <listitem>
-     <para>
-      <literal>[ String ] -> AttrSet -> AttrSet -> Bool</literal>
-     </para>
-     <variablelist>
-      <varlistentry>
-       <term>
-        <varname>path</varname>
-       </term>
-       <listitem>
-        <para>
-         The path to the values in the left and right hand sides.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>l</varname>
-       </term>
-       <listitem>
-        <para>
-         The left hand side value.
-        </para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term>
-        <varname>r</varname>
-       </term>
-       <listitem>
-        <para>
-         The right hand side value.
-        </para>
-       </listitem>
-      </varlistentry>
-     </variablelist>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>lhs</varname>
-    </term>
-    <listitem>
-     <para>
-      The left hand attribute set of the merge.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>rhs</varname>
-    </term>
-    <listitem>
-     <para>
-      The right hand attribute set of the merge.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.recursiveUpdateUntil-example">
-   <title>Recursively merging two attribute sets</title>
-<programlisting><![CDATA[
-lib.attrsets.recursiveUpdateUntil (path: l: r: path == ["foo"])
-  {
-    # first attribute set
-    foo.bar = 1;
-    foo.baz = 2;
-    bar = 3;
-  }
-  {
-    #second attribute set
-    foo.bar = 1;
-    foo.quz = 2;
-    baz = 4;
-  }
-=> {
-  foo.bar = 1; # 'foo.*' from the second set
-  foo.quz = 2; #
-  bar = 3;     # 'bar' from the first set
-  baz = 4;     # 'baz' from the second set
-}
-     ]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.recursiveUpdate">
-  <title><function>lib.attrsets.recursiveUpdate</function></title>
-
-  <subtitle><literal>recursiveUpdate :: AttrSet -> AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.recursiveUpdate" />
-
-  <para>
-   A recursive variant of the update operator <literal>//</literal>. The recursion stops when one of the attribute values is not an attribute set, in which case the right hand side value takes precedence over the left hand side value.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>lhs</varname>
-    </term>
-    <listitem>
-     <para>
-      The left hand attribute set of the merge.
-     </para>
-    </listitem>
-   </varlistentry>
-   <varlistentry>
-    <term>
-     <varname>rhs</varname>
-    </term>
-    <listitem>
-     <para>
-      The right hand attribute set of the merge.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.recursiveUpdate-example">
-   <title>Recursively merging two attribute sets</title>
-<programlisting><![CDATA[
-recursiveUpdate
-  {
-    boot.loader.grub.enable = true;
-    boot.loader.grub.device = "/dev/hda";
-  }
-  {
-    boot.loader.grub.device = "";
-  }
-=> {
-  boot.loader.grub.enable = true;
-  boot.loader.grub.device = "";
-}
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.recurseIntoAttrs">
-  <title><function>lib.attrsets.recurseIntoAttrs</function></title>
-
-  <subtitle><literal>recurseIntoAttrs :: AttrSet -> AttrSet</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.recurseIntoAttrs" />
-
-  <para>
-   Make various Nix tools consider the contents of the resulting attribute set when looking for what to build, find, etc.
-  </para>
-
-  <para>
-   This function only affects a single attribute set; it does not apply itself recursively for nested attribute sets.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>attrs</varname>
-    </term>
-    <listitem>
-     <para>
-      An attribute set to scan for derivations.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.recurseIntoAttrs-example">
-   <title>Making Nix look inside an attribute set</title>
-<programlisting><![CDATA[
-{ pkgs ? import <nixpkgs> {} }:
-{
-  myTools = pkgs.lib.recurseIntoAttrs {
-    inherit (pkgs) hello figlet;
-  };
-}
-]]></programlisting>
-  </example>
- </section>
-
- <section xml:id="function-library-lib.attrsets.cartesianProductOfSets">
-  <title><function>lib.attrsets.cartesianProductOfSets</function></title>
-
-  <subtitle><literal>cartesianProductOfSets :: AttrSet -> [ AttrSet ]</literal>
-  </subtitle>
-
-  <xi:include href="./locations.xml" xpointer="lib.attrsets.cartesianProductOfSets" />
-
-  <para>
-   Return the cartesian product of attribute set value combinations.
-  </para>
-
-  <variablelist>
-   <varlistentry>
-    <term>
-     <varname>set</varname>
-    </term>
-    <listitem>
-     <para>
-      An attribute set with attributes that carry lists of values.
-     </para>
-    </listitem>
-   </varlistentry>
-  </variablelist>
-
-  <example xml:id="function-library-lib.attrsets.cartesianProductOfSets-example">
-   <title>Creating the cartesian product of a list of attribute values</title>
-<programlisting><![CDATA[
-cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
-=> [
-     { a = 1; b = 10; }
-     { a = 1; b = 20; }
-     { a = 2; b = 10; }
-     { a = 2; b = 20; }
-   ]
-]]></programlisting>
-  </example>
- </section>
-</section>
diff --git a/lib/asserts.nix b/lib/asserts.nix
index 9ae357cbc935e..98e0b490acf29 100644
--- a/lib/asserts.nix
+++ b/lib/asserts.nix
@@ -16,11 +16,15 @@ rec {
        assertMsg :: Bool -> String -> Bool
   */
   # TODO(Profpatsch): add tests that check stderr
-  assertMsg = pred: msg:
+  assertMsg =
+    # Predicate that needs to succeed, otherwise `msg` is thrown
+    pred:
+    # Message to throw in case `pred` fails
+    msg:
     pred || builtins.throw msg;
 
-  /* Specialized `assertMsg` for checking if val is one of the elements
-     of a list. Useful for checking enums.
+  /* Specialized `assertMsg` for checking if `val` is one of the elements
+     of the list `xs`. Useful for checking enums.
 
      Example:
        let sslLibrary = "libressl";
@@ -33,7 +37,14 @@ rec {
      Type:
        assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
   */
-  assertOneOf = name: val: xs: assertMsg
+  assertOneOf =
+    # The name of the variable the user entered `val` into, for inclusion in the error message
+    name:
+    # The value of what the user provided, to be compared against the values in `xs`
+    val:
+    # The list of valid values
+    xs:
+    assertMsg
     (lib.elem val xs)
     "${name} must be one of ${
       lib.generators.toPretty {} xs}, but is: ${
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index 8b5c0ef4cea62..511d619a1dc2f 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -20,13 +20,22 @@ rec {
        => 3
        attrByPath ["z" "z"] 6 x
        => 6
+
+     Type:
+       attrByPath :: [String] -> Any -> AttrSet -> Any
   */
-  attrByPath = attrPath: default: e:
+  attrByPath =
+    # A list of strings representing the attribute path to return from `set`
+    attrPath:
+    # Default value if `attrPath` does not resolve to an existing value
+    default:
+    # The nested attribute set to select values from
+    set:
     let attr = head attrPath;
     in
-      if attrPath == [] then e
-      else if e ? ${attr}
-      then attrByPath (tail attrPath) default e.${attr}
+      if attrPath == [] then set
+      else if set ? ${attr}
+      then attrByPath (tail attrPath) default set.${attr}
       else default;
 
   /* Return if an attribute from nested attribute set exists.
@@ -38,8 +47,14 @@ rec {
        hasAttrByPath ["z" "z"] x
        => false
 
+    Type:
+      hasAttrByPath :: [String] -> AttrSet -> Bool
   */
-  hasAttrByPath = attrPath: e:
+  hasAttrByPath =
+    # A list of strings representing the attribute path to check from `set`
+    attrPath:
+    # The nested attribute set to check
+    e:
     let attr = head attrPath;
     in
       if attrPath == [] then true
@@ -48,13 +63,20 @@ rec {
       else false;
 
 
-  /* Return nested attribute set in which an attribute is set.
+  /* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
 
      Example:
        setAttrByPath ["a" "b"] 3
        => { a = { b = 3; }; }
+
+     Type:
+       setAttrByPath :: [String] -> Any -> AttrSet
   */
-  setAttrByPath = attrPath: value:
+  setAttrByPath =
+    # A list of strings representing the attribute path to set
+    attrPath:
+    # The value to set at the location described by `attrPath`
+    value:
     let
       len = length attrPath;
       atDepth = n:
@@ -63,8 +85,8 @@ rec {
         else { ${elemAt attrPath n} = atDepth (n + 1); };
     in atDepth 0;
 
-  /* Like `attrByPath' without a default value. If it doesn't find the
-     path it will throw.
+  /* Like `attrByPath', but without a default value. If it doesn't find the
+     path it will throw an error.
 
      Example:
        x = { a = { b = 3; }; }
@@ -72,10 +94,17 @@ rec {
        => 3
        getAttrFromPath ["z" "z"] x
        => error: cannot find attribute `z.z'
+
+     Type:
+       getAttrFromPath :: [String] -> AttrSet -> Value
   */
-  getAttrFromPath = attrPath:
+  getAttrFromPath =
+    # A list of strings representing the attribute path to get from `set`
+    attrPath:
+    # The nested attribute set to find the value in.
+    set:
     let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
-    in attrByPath attrPath (abort errorMsg);
+    in attrByPath attrPath (abort errorMsg) set;
 
   /* Map each attribute in the given set and merge them into a new attribute set.
 
@@ -101,19 +130,23 @@ rec {
 
      Takes a list of updates to apply and an attribute set to apply them to,
      and returns the attribute set with the updates applied. Updates are
-     represented as { path = ...; update = ...; } values, where `path` is a
+     represented as `{ path = ...; update = ...; }` values, where `path` is a
      list of strings representing the attribute path that should be updated,
      and `update` is a function that takes the old value at that attribute path
      as an argument and returns the new
      value it should be.
 
      Properties:
+
      - Updates to deeper attribute paths are applied before updates to more
        shallow attribute paths
+
      - Multiple updates to the same attribute path are applied in the order
        they appear in the update list
+
      - If any but the last `path` element leads into a value that is not an
        attribute set, an error is thrown
+
      - If there is an update for an attribute path that doesn't exist,
        accessing the argument in the update function causes an error, but
        intermediate attribute sets are implicitly created as needed
@@ -134,6 +167,9 @@ rec {
          }
        ] { a.b.c = 0; }
        => { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
+
+    Type:
+      updateManyAttrsByPath :: [AttrSet] -> AttrSet -> AttrSet
   */
   updateManyAttrsByPath = let
     # When recursing into attributes, instead of updating the `path` of each
@@ -199,8 +235,15 @@ rec {
      Example:
        attrVals ["a" "b" "c"] as
        => [as.a as.b as.c]
+
+     Type:
+       attrVals :: [String] -> AttrSet -> [Any]
   */
-  attrVals = nameList: set: map (x: set.${x}) nameList;
+  attrVals =
+    # The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set
+    nameList:
+    # The set to get attribute values from
+    set: map (x: set.${x}) nameList;
 
 
   /* Return the values of all attributes in the given set, sorted by
@@ -209,6 +252,8 @@ rec {
      Example:
        attrValues {c = 3; a = 1; b = 2;}
        => [1 2 3]
+     Type:
+       attrValues :: AttrSet -> [Any]
   */
   attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
 
@@ -219,8 +264,15 @@ rec {
      Example:
        getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
        => { a = 1; b = 2; }
+
+     Type:
+       getAttrs :: [String] -> AttrSet -> AttrSet
   */
-  getAttrs = names: attrs: genAttrs names (name: attrs.${name});
+  getAttrs =
+    # A list of attribute names to get out of `set`
+    names:
+    # The set to get the named attributes from
+    attrs: genAttrs names (name: attrs.${name});
 
   /* Collect each attribute named `attr' from a list of attribute
      sets.  Sets that don't contain the named attribute are ignored.
@@ -228,6 +280,9 @@ rec {
      Example:
        catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
        => [1 2]
+
+     Type:
+       catAttrs :: String -> [AttrSet] -> [Any]
   */
   catAttrs = builtins.catAttrs or
     (attr: l: concatLists (map (s: if s ? ${attr} then [s.${attr}] else []) l));
@@ -239,8 +294,15 @@ rec {
      Example:
        filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
        => { foo = 1; }
+
+     Type:
+       filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet
   */
-  filterAttrs = pred: set:
+  filterAttrs =
+    # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
+    pred:
+    # The attribute set to filter
+    set:
     listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
 
 
@@ -250,8 +312,15 @@ rec {
      Example:
        filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; }
        => { foo = {}; }
+
+     Type:
+       filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet
   */
-  filterAttrsRecursive = pred: set:
+  filterAttrsRecursive =
+    # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
+    pred:
+    # The attribute set to filter
+    set:
     listToAttrs (
       concatMap (name:
         let v = set.${name}; in
@@ -269,23 +338,28 @@ rec {
      Example:
        foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }]
        => { a = [ 2 3 ]; }
+
+     Type:
+       foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any
   */
-  foldAttrs = op: nul:
+  foldAttrs =
+    # A function, given a value and a collector combines the two.
+    op:
+    # The starting value.
+    nul:
+    # A list of attribute sets to fold together by key.
+    list_of_attrs:
     foldr (n: a:
         foldr (name: o:
           o // { ${name} = op n.${name} (a.${name} or nul); }
         ) a (attrNames n)
-    ) {};
+    ) {} list_of_attrs;
 
 
   /* Recursively collect sets that verify a given predicate named `pred'
      from the set `attrs'.  The recursion is stopped when the predicate is
      verified.
 
-     Type:
-       collect ::
-         (AttrSet -> Bool) -> AttrSet -> [x]
-
      Example:
        collect isList { a = { b = ["b"]; }; c = [1]; }
        => [["b"] [1]]
@@ -293,8 +367,15 @@ rec {
        collect (x: x ? outPath)
           { a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
        => [{ outPath = "a/"; } { outPath = "b/"; }]
+
+     Type:
+       collect :: (AttrSet -> Bool) -> AttrSet -> [x]
   */
-  collect = pred: attrs:
+  collect =
+  # Given an attribute's value, determine if recursion should stop.
+  pred:
+  # The attribute set to recursively collect.
+  attrs:
     if pred attrs then
       [ attrs ]
     else if isAttrs attrs then
@@ -312,8 +393,12 @@ rec {
            { a = 2; b = 10; }
            { a = 2; b = 20; }
          ]
+     Type:
+     cartesianProductOfSets :: AttrSet -> [AttrSet]
   */
-  cartesianProductOfSets = attrsOfLists:
+  cartesianProductOfSets =
+    # Attribute set with attributes that are lists of values
+    attrsOfLists:
     foldl' (listOfAttrs: attrName:
       concatMap (attrs:
         map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName}
@@ -321,25 +406,32 @@ rec {
     ) [{}] (attrNames attrsOfLists);
 
 
-  /* Utility function that creates a {name, value} pair as expected by
-     builtins.listToAttrs.
+  /* Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`.
 
      Example:
        nameValuePair "some" 6
        => { name = "some"; value = 6; }
+
+     Type:
+       nameValuePair :: String -> Any -> AttrSet
   */
-  nameValuePair = name: value: { inherit name value; };
+  nameValuePair =
+    # Attribute name
+    name:
+    # Attribute value
+    value:
+    { inherit name value; };
 
 
-  /* Apply a function to each element in an attribute set.  The
-     function takes two arguments --- the attribute name and its value
-     --- and returns the new value for the attribute.  The result is a
-     new attribute set.
+  /* Apply a function to each element in an attribute set, creating a new attribute set.
 
      Example:
        mapAttrs (name: value: name + "-" + value)
           { x = "foo"; y = "bar"; }
        => { x = "x-foo"; y = "y-bar"; }
+
+     Type:
+       mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet
   */
   mapAttrs = builtins.mapAttrs or
     (f: set:
@@ -354,24 +446,35 @@ rec {
        mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
           { x = "a"; y = "b"; }
        => { foo_x = "bar-a"; foo_y = "bar-b"; }
+
+     Type:
+       mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet
   */
-  mapAttrs' = f: set:
+  mapAttrs' =
+    # A function, given an attribute's name and value, returns a new `nameValuePair`.
+    f:
+    # Attribute set to map over.
+    set:
     listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
 
 
   /* Call a function for each attribute in the given set and return
      the result in a list.
 
-     Type:
-       mapAttrsToList ::
-         (String -> a -> b) -> AttrSet -> [b]
-
      Example:
        mapAttrsToList (name: value: name + value)
           { x = "a"; y = "b"; }
        => [ "xa" "yb" ]
+
+     Type:
+       mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b]
+
   */
-  mapAttrsToList = f: attrs:
+  mapAttrsToList =
+    # A function, given an attribute's name and value, returns a new value.
+    f:
+    # Attribute set to map over.
+    attrs:
     map (name: f name attrs.${name}) (attrNames attrs);
 
 
@@ -379,16 +482,20 @@ rec {
      attribute sets.  Also, the first argument of the argument
      function is a *list* of the names of the containing attributes.
 
-     Type:
-       mapAttrsRecursive ::
-         ([String] -> a -> b) -> AttrSet -> AttrSet
-
      Example:
        mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
          { n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
        => { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
+
+     Type:
+       mapAttrsRecursive :: ([String] -> a -> b) -> AttrSet -> AttrSet
   */
-  mapAttrsRecursive = mapAttrsRecursiveCond (as: true);
+  mapAttrsRecursive =
+    # A function, given a list of attribute names and a value, returns a new value.
+    f:
+    # Set to recursively map over.
+    set:
+    mapAttrsRecursiveCond (as: true) f set;
 
 
   /* Like `mapAttrsRecursive', but it takes an additional predicate
@@ -397,10 +504,6 @@ rec {
      recurse, but does apply the map function.  If it returns true, it
      does recurse, and does not apply the map function.
 
-     Type:
-       mapAttrsRecursiveCond ::
-         (AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
-
      Example:
        # To prevent recursing into derivations (which are attribute
        # sets with the attribute "type" equal to "derivation"):
@@ -408,8 +511,17 @@ rec {
          (as: !(as ? "type" && as.type == "derivation"))
          (x: ... do something ...)
          attrs
+
+     Type:
+       mapAttrsRecursiveCond :: (AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
   */
-  mapAttrsRecursiveCond = cond: f: set:
+  mapAttrsRecursiveCond =
+    # A function, given the attribute set the recursion is currently at, determine if to recurse deeper into that attribute set.
+    cond:
+    # A function, given a list of attribute names and a value, returns a new value.
+    f:
+    # Attribute set to recursively map over.
+    set:
     let
       recurse = path:
         let
@@ -428,13 +540,20 @@ rec {
      Example:
        genAttrs [ "foo" "bar" ] (name: "x_" + name)
        => { foo = "x_foo"; bar = "x_bar"; }
+
+     Type:
+       genAttrs :: [ String ] -> (String -> Any) -> AttrSet
   */
-  genAttrs = names: f:
+  genAttrs =
+    # Names of values in the resulting attribute set.
+    names:
+    # A function, given the name of the attribute, returns the attribute's value.
+    f:
     listToAttrs (map (n: nameValuePair n (f n)) names);
 
 
   /* Check whether the argument is a derivation. Any set with
-     { type = "derivation"; } counts as a derivation.
+     `{ type = "derivation"; }` counts as a derivation.
 
      Example:
        nixpkgs = import <nixpkgs> {}
@@ -442,25 +561,36 @@ rec {
        => true
        isDerivation "foobar"
        => false
+
+     Type:
+       isDerivation :: Any -> Bool
   */
-  isDerivation = x: x.type or null == "derivation";
+  isDerivation =
+    # Value to check.
+    value: value.type or null == "derivation";
 
-  /* Converts a store path to a fake derivation. */
-  toDerivation = path:
-    let
-      path' = builtins.storePath path;
-      res =
-        { type = "derivation";
-          name = sanitizeDerivationName (builtins.substring 33 (-1) (baseNameOf path'));
-          outPath = path';
-          outputs = [ "out" ];
-          out = res;
-          outputName = "out";
-        };
+   /* Converts a store path to a fake derivation.
+
+      Type:
+        toDerivation :: Path -> Derivation
+   */
+   toDerivation =
+     # A store path to convert to a derivation.
+     path:
+     let
+       path' = builtins.storePath path;
+       res =
+         { type = "derivation";
+           name = sanitizeDerivationName (builtins.substring 33 (-1) (baseNameOf path'));
+           outPath = path';
+           outputs = [ "out" ];
+           out = res;
+           outputName = "out";
+         };
     in res;
 
 
-  /* If `cond' is true, return the attribute set `as',
+  /* If `cond` is true, return the attribute set `as`,
      otherwise an empty attribute set.
 
      Example:
@@ -468,47 +598,82 @@ rec {
        => { my = "set"; }
        optionalAttrs (false) { my = "set"; }
        => { }
+
+     Type:
+       optionalAttrs :: Bool -> AttrSet
   */
-  optionalAttrs = cond: as: if cond then as else {};
+  optionalAttrs =
+    # Condition under which the `as` attribute set is returned.
+    cond:
+    # The attribute set to return if `cond` is `true`.
+    as:
+    if cond then as else {};
 
 
-  /* Merge sets of attributes and use the function f to merge attributes
+  /* Merge sets of attributes and use the function `f` to merge attributes
      values.
 
      Example:
        zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
        => { a = ["x" "y"]; }
+
+     Type:
+       zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
   */
-  zipAttrsWithNames = names: f: sets:
+  zipAttrsWithNames =
+    # List of attribute names to zip.
+    names:
+    # A function, accepts an attribute name, all the values, and returns a combined value.
+    f:
+    # List of values from the list of attribute sets.
+    sets:
     listToAttrs (map (name: {
       inherit name;
       value = f name (catAttrs name sets);
     }) names);
 
-  /* Implementation note: Common names appear multiple times in the list of
+
+  /* Merge sets of attributes and use the function f to merge attribute values.
+     Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`.
+
+     Implementation note: Common names appear multiple times in the list of
      names, hopefully this does not affect the system because the maximal
-     laziness avoid computing twice the same expression and listToAttrs does
+     laziness avoid computing twice the same expression and `listToAttrs` does
      not care about duplicated attribute names.
 
      Example:
        zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
        => { a = ["x" "y"]; b = ["z"] }
+
+     Type:
+     zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
   */
   zipAttrsWith =
     builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
-  /* Like `zipAttrsWith' with `(name: values: values)' as the function.
 
-    Example:
-      zipAttrs [{a = "x";} {a = "y"; b = "z";}]
-      => { a = ["x" "y"]; b = ["z"] }
+
+  /* Merge sets of attributes and combine each attribute value in to a list.
+
+     Like `lib.attrsets.zipAttrsWith' with `(name: values: values)' as the function.
+
+     Example:
+       zipAttrs [{a = "x";} {a = "y"; b = "z";}]
+       => { a = ["x" "y"]; b = ["z"] }
+
+     Type:
+       zipAttrs :: [ AttrSet ] -> AttrSet
   */
-  zipAttrs = zipAttrsWith (name: values: values);
+  zipAttrs =
+    # List of attribute sets to zip together.
+    sets:
+    zipAttrsWith (name: values: values) sets;
+
 
   /* Does the same as the update operator '//' except that attributes are
      merged until the given predicate is verified.  The predicate should
      accept 3 arguments which are the path to reach the attribute, a part of
      the first attribute set and a part of the second attribute set.  When
-     the predicate is verified, the value of the first attribute set is
+     the predicate is satisfied, the value of the first attribute set is
      replaced by the value of the second attribute set.
 
      Example:
@@ -524,15 +689,23 @@ rec {
          baz = 4;
        }
 
-       returns: {
+       => {
          foo.bar = 1; # 'foo.*' from the second set
          foo.quz = 2; #
          bar = 3;     # 'bar' from the first set
          baz = 4;     # 'baz' from the second set
        }
 
-     */
-  recursiveUpdateUntil = pred: lhs: rhs:
+     Type:
+       recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
+  */
+  recursiveUpdateUntil =
+    # Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
+    pred:
+    # Left attribute set of the merge.
+    lhs:
+    # Right attribute set of the merge.
+    rhs:
     let f = attrPath:
       zipAttrsWith (n: values:
         let here = attrPath ++ [n]; in
@@ -544,6 +717,7 @@ rec {
       );
     in f [] [rhs lhs];
 
+
   /* A recursive variant of the update operator ‘//’.  The recursion
      stops when one of the attribute values is not an attribute set,
      in which case the right hand side value takes precedence over the
@@ -562,16 +736,32 @@ rec {
          boot.loader.grub.device = "";
        }
 
-     */
-  recursiveUpdate = recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs));
+     Type:
+     recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
+  */
+  recursiveUpdate =
+    # Left attribute set of the merge.
+    lhs:
+    # Right attribute set of the merge.
+    rhs:
+    recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
+
 
   /* Returns true if the pattern is contained in the set. False otherwise.
 
      Example:
        matchAttrs { cpu = {}; } { cpu = { bits = 64; }; }
        => true
-   */
-  matchAttrs = pattern: attrs: assert isAttrs pattern;
+
+     Type:
+       matchAttrs :: AttrSet -> AttrSet -> Bool
+  */
+  matchAttrs =
+    # Attribute set strucutre to match
+    pattern:
+    # Attribute set to find patterns in
+    attrs:
+    assert isAttrs pattern;
     all id (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
       let pat = head values; val = elemAt values 1; in
       if length values == 1 then false
@@ -579,6 +769,7 @@ rec {
       else pat == val
     ) [pattern attrs]));
 
+
   /* Override only the attributes that are already present in the old set
     useful for deep-overriding.
 
@@ -589,10 +780,18 @@ rec {
       => { b = 2; }
       overrideExisting { a = 3; b = 2; } { a = 1; }
       => { a = 1; b = 2; }
+
+    Type:
+      overrideExisting :: AttrSet -> AttrSet -> AttrSet
   */
-  overrideExisting = old: new:
+  overrideExisting =
+    # Original attribute set
+    old:
+    # Attribute set with attributes to override in `old`.
+    new:
     mapAttrs (name: value: new.${name} or value) old;
 
+
   /* Turns a list of strings into a human-readable description of those
     strings represented as an attribute path. The result of this function is
     not intended to be machine-readable.
@@ -602,44 +801,120 @@ rec {
       => "foo.\"10\".bar"
       showAttrPath []
       => "<root attribute path>"
+
+    Type:
+      showAttrPath :: [String] -> String
   */
-  showAttrPath = path:
+  showAttrPath =
+    # Attribute path to render to a string
+    path:
     if path == [] then "<root attribute path>"
     else concatMapStringsSep "." escapeNixIdentifier path;
 
+
   /* Get a package output.
      If no output is found, fallback to `.out` and then to the default.
 
      Example:
        getOutput "dev" pkgs.openssl
        => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
+
+     Type:
+       getOutput :: String -> Derivation -> String
   */
   getOutput = output: pkg:
     if ! pkg ? outputSpecified || ! pkg.outputSpecified
       then pkg.${output} or pkg.out or pkg
       else pkg;
 
+  /* Get a package's `bin` output.
+     If the output does not exist, fallback to `.out` and then to the default.
+
+     Example:
+       getOutput pkgs.openssl
+       => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"
+
+     Type:
+       getOutput :: Derivation -> String
+  */
   getBin = getOutput "bin";
+
+
+  /* Get a package's `lib` output.
+     If the output does not exist, fallback to `.out` and then to the default.
+
+     Example:
+       getOutput pkgs.openssl
+       => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"
+
+     Type:
+       getOutput :: Derivation -> String
+  */
   getLib = getOutput "lib";
+
+
+  /* Get a package's `dev` output.
+     If the output does not exist, fallback to `.out` and then to the default.
+
+     Example:
+       getOutput pkgs.openssl
+       => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
+
+     Type:
+       getOutput :: Derivation -> String
+  */
   getDev = getOutput "dev";
+
+
+  /* Get a package's `man` output.
+     If the output does not exist, fallback to `.out` and then to the default.
+
+     Example:
+       getOutput pkgs.openssl
+       => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"
+
+     Type:
+       getOutput :: Derivation -> String
+  */
   getMan = getOutput "man";
 
-  /* Pick the outputs of packages to place in buildInputs */
-  chooseDevOutputs = builtins.map getDev;
+  /* Pick the outputs of packages to place in `buildInputs` */
+  chooseDevOutputs =
+    # List of packages to pick `dev` outputs from
+    drvs:
+    builtins.map getDev drvs;
 
   /* Make various Nix tools consider the contents of the resulting
      attribute set when looking for what to build, find, etc.
 
      This function only affects a single attribute set; it does not
      apply itself recursively for nested attribute sets.
+
+     Example:
+       { pkgs ? import <nixpkgs> {} }:
+       {
+         myTools = pkgs.lib.recurseIntoAttrs {
+           inherit (pkgs) hello figlet;
+         };
+       }
+
+     Type:
+       recurseIntoAttrs :: AttrSet -> AttrSet
    */
   recurseIntoAttrs =
-    attrs: attrs // { recurseForDerivations = true; };
+    # An attribute set to scan for derivations.
+    attrs:
+    attrs // { recurseForDerivations = true; };
 
   /* Undo the effect of recurseIntoAttrs.
+
+     Type:
+       recurseIntoAttrs :: AttrSet -> AttrSet
    */
   dontRecurseIntoAttrs =
-    attrs: attrs // { recurseForDerivations = false; };
+    # An attribute set to not scan for derivations.
+    attrs:
+    attrs // { recurseForDerivations = false; };
 
   /* `unionOfDisjoint x y` is equal to `x // y // z` where the
      attrnames in `z` are the intersection of the attrnames in `x` and
@@ -655,9 +930,9 @@ rec {
     in
       (x // y) // mask;
 
-  /*** deprecated stuff ***/
-
+  # deprecated
   zipWithNames = zipAttrsWithNames;
+  # deprecated
   zip = builtins.trace
     "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
 }