Merge pull request #312393 from hsjobeki/doc/lib-fixedpoints

doc: migrate lib.fixedPoints to doc-comment format
This commit is contained in:
Daniel Sidhion 2024-05-23 00:03:19 -07:00 committed by GitHub
commit 43e364791b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,6 @@
{ lib, ... }: { lib, ... }:
rec { rec {
/* /**
`fix f` computes the fixed point of the given function `f`. In other words, the return value is `x` in `x = f x`. `fix f` computes the fixed point of the given function `f`. In other words, the return value is `x` in `x = f x`.
`f` must be a lazy function. `f` must be a lazy function.
@ -63,27 +63,52 @@ rec {
See [`extends`](#function-library-lib.fixedPoints.extends) for an example use case. See [`extends`](#function-library-lib.fixedPoints.extends) for an example use case.
There `self` is also often called `final`. There `self` is also often called `final`.
Type: fix :: (a -> a) -> a
Example: # Inputs
fix (self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; })
=> { bar = "bar"; foo = "foo"; foobar = "foobar"; }
fix (self: [ 1 2 (elemAt self 0 + elemAt self 1) ]) `f`
=> [ 1 2 3 ]
: 1\. Function argument
# Type
```
fix :: (a -> a) -> a
```
# Examples
:::{.example}
## `lib.fixedPoints.fix` usage example
```nix
fix (self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; })
=> { bar = "bar"; foo = "foo"; foobar = "foobar"; }
fix (self: [ 1 2 (elemAt self 0 + elemAt self 1) ])
=> [ 1 2 3 ]
```
:::
*/ */
fix = f: let x = f x; in x; fix = f: let x = f x; in x;
/* /**
A variant of `fix` that records the original recursive attribute set in the A variant of `fix` that records the original recursive attribute set in the
result, in an attribute named `__unfix__`. result, in an attribute named `__unfix__`.
This is useful in combination with the `extends` function to This is useful in combination with the `extends` function to
implement deep overriding. implement deep overriding.
# Inputs
`f`
: 1\. Function argument
*/ */
fix' = f: let x = f x // { __unfix__ = f; }; in x; fix' = f: let x = f x // { __unfix__ = f; }; in x;
/* /**
Return the fixpoint that `f` converges to when called iteratively, starting Return the fixpoint that `f` converges to when called iteratively, starting
with the input `x`. with the input `x`.
@ -92,7 +117,22 @@ rec {
0 0
``` ```
Type: (a -> a) -> a -> a
# Inputs
`f`
: 1\. Function argument
`x`
: 2\. Function argument
# Type
```
(a -> a) -> a -> a
```
*/ */
converge = f: x: converge = f: x:
let let
@ -102,7 +142,7 @@ rec {
then x then x
else converge f x'; else converge f x';
/* /**
Extend a function using an overlay. Extend a function using an overlay.
Overlays allow modifying and extending fixed-point functions, specifically ones returning attribute sets. Overlays allow modifying and extending fixed-point functions, specifically ones returning attribute sets.
@ -217,32 +257,50 @@ rec {
``` ```
::: :::
Type:
extends :: (Attrs -> Attrs -> Attrs) # The overlay to apply to the fixed-point function
-> (Attrs -> Attrs) # A fixed-point function
-> (Attrs -> Attrs) # The resulting fixed-point function
Example: # Inputs
f = final: { a = 1; b = final.a + 2; }
fix f `overlay`
=> { a = 1; b = 3; }
fix (extends (final: prev: { a = prev.a + 10; }) f) : The overlay to apply to the fixed-point function
=> { a = 11; b = 13; }
fix (extends (final: prev: { b = final.a + 5; }) f) `f`
=> { a = 1; b = 6; }
fix (extends (final: prev: { c = final.a + final.b; }) f) : The fixed-point function
=> { a = 1; b = 3; c = 4; }
# Type
```
extends :: (Attrs -> Attrs -> Attrs) # The overlay to apply to the fixed-point function
-> (Attrs -> Attrs) # A fixed-point function
-> (Attrs -> Attrs) # The resulting fixed-point function
```
# Examples
:::{.example}
## `lib.fixedPoints.extends` usage example
```nix
f = final: { a = 1; b = final.a + 2; }
fix f
=> { a = 1; b = 3; }
fix (extends (final: prev: { a = prev.a + 10; }) f)
=> { a = 11; b = 13; }
fix (extends (final: prev: { b = final.a + 5; }) f)
=> { a = 1; b = 6; }
fix (extends (final: prev: { c = final.a + final.b; }) f)
=> { a = 1; b = 3; c = 4; }
```
:::
*/ */
extends = extends =
# The overlay to apply to the fixed-point function
overlay: overlay:
# The fixed-point function
f: f:
# Wrap with parenthesis to prevent nixdoc from rendering the `final` argument in the documentation
# The result should be thought of as a function, the argument of that function is not an argument to `extends` itself # The result should be thought of as a function, the argument of that function is not an argument to `extends` itself
( (
final: final:
@ -252,10 +310,29 @@ rec {
prev // overlay final prev prev // overlay final prev
); );
/* /**
Compose two extending functions of the type expected by 'extends' Compose two extending functions of the type expected by 'extends'
into one where changes made in the first are available in the into one where changes made in the first are available in the
'super' of the second 'super' of the second
# Inputs
`f`
: 1\. Function argument
`g`
: 2\. Function argument
`final`
: 3\. Function argument
`prev`
: 4\. Function argument
*/ */
composeExtensions = composeExtensions =
f: g: final: prev: f: g: final: prev:
@ -263,7 +340,7 @@ rec {
prev' = prev // fApplied; prev' = prev // fApplied;
in fApplied // g final prev'; in fApplied // g final prev';
/* /**
Compose several extending functions of the type expected by 'extends' into Compose several extending functions of the type expected by 'extends' into
one where changes made in preceding functions are made available to one where changes made in preceding functions are made available to
subsequent ones. subsequent ones.
@ -276,7 +353,7 @@ rec {
composeManyExtensions = composeManyExtensions =
lib.foldr (x: y: composeExtensions x y) (final: prev: {}); lib.foldr (x: y: composeExtensions x y) (final: prev: {});
/* /**
Create an overridable, recursive attribute set. For example: Create an overridable, recursive attribute set. For example:
``` ```
@ -298,9 +375,20 @@ rec {
*/ */
makeExtensible = makeExtensibleWithCustomName "extend"; makeExtensible = makeExtensibleWithCustomName "extend";
/* /**
Same as `makeExtensible` but the name of the extending attribute is Same as `makeExtensible` but the name of the extending attribute is
customized. customized.
# Inputs
`extenderName`
: 1\. Function argument
`rattrs`
: 2\. Function argument
*/ */
makeExtensibleWithCustomName = extenderName: rattrs: makeExtensibleWithCustomName = extenderName: rattrs:
fix' (self: (rattrs self) // { fix' (self: (rattrs self) // {