Skip to content

Commit

Permalink
Doc: simplify examples
Browse files Browse the repository at this point in the history
  • Loading branch information
hsjobeki committed Jul 12, 2024
1 parent db6a4df commit 126a045
Showing 1 changed file with 101 additions and 37 deletions.
138 changes: 101 additions & 37 deletions lib/fixed-points.nix
Original file line number Diff line number Diff line change
Expand Up @@ -311,36 +311,7 @@ rec {
);

/**
Compose two [`overlays`](#chap-overlays) and returns the resulting attribute set.
```nix
let
original =
final: { r = final.a + final.b; a = 1; b = 2; };
f =
final: prev: { b = final.c * prev.b; c = 3; };
g =
final: prev: { c = 10; cPrev = prev.c; r = toString prev.r; };
# Compute the fixed point.
# As we only call our functions once, `final` above only takes on the value of `fixedpoint`.
fixedpoint =
lib.fix
(lib.extends
(lib.composeExtensions f g)
original
);
in fixedpoint
=> {
a = 1;
b = 20;
c = 10;
cPrev = 3;
r = "21";
}
```
See also [`fix`](#function-library-lib.fixedPoints.fix), [`extends`](#function-library-lib.fixedPoints.extends).
Composes two [`overlays`](#chap-overlays) and returns a single overlay function that combines them.
:::{.note}
The result is produced by using the update operator `//`.
Expand All @@ -363,7 +334,8 @@ rec {
`prev`
: The return value of the original function that is extended by the overlays `f` and `g`.
: The return value of the preceding function that is extended by the overlays `f` and `g`.
If `composeExtensions f g` is itself used in a composition of overlays, then any overlays that precede it can be considered to be part of "the original function".
# Type
Expand All @@ -373,8 +345,34 @@ rec {
let
OverlayFn :: ( { ... } -> { ... } -> { ... } );
in
composeExtensions :: OverlayFn -> OverlayFn -> { ... } -> { ... } -> { ... }
composeExtensions :: OverlayFn -> OverlayFn -> OverlayFn
```
# Examples
:::{.example}
## `lib.fixedPoints.composeExtensions` usage example
```nix
let
# Each overlay function has 'final' and 'prev' as arguments.
overlayA = final: prev: { b = final.c; c = 3; };
overlayB = final: prev: { c = 10; cPrev = prev.c; };
extensions = composeExtensions overlayA overlayB;
# Calculate the fixed point of all composed overlays.
# With an empty attribute set as the initial value.
fixedpoint = lib.fix (final: extensions final { } );
in fixedpoint
=>
{
b = 10;
c = 10;
cPrev = 3;
}
```
:::
*/
composeExtensions =
f: g: final: prev:
Expand All @@ -383,13 +381,16 @@ rec {
in fApplied // g final prev';

/**
Composes a list of [`overlays`](#chap-overlays) and returns the resulting attribute set.
Composes a list of [`overlays`](#chap-overlays) and returns a single overlay function that combines them.
# Inputs
`extensions`
: A list of overlay functions.
: A list of overlay functions
:::{.note}
The order of the overlays in the list is important.
:::
: Each overlay function takes two arguments, `final` and `prev`, and returns an attribute set.
- `final` is the result of the fixed-point function, with all overlays applied.
Expand All @@ -398,6 +399,7 @@ rec {
`final`
: The return value of the original function that is extended by the overlays `f` and `g`.
If `composeManyExtensions extensions` is itself used in a composition of overlays, then any overlays that precede it can be considered to be part of "the original function".
`prev`
Expand All @@ -413,6 +415,68 @@ rec {
in
composeManyExtensions :: [ OverlayFn ] -> OverlayFn
```
# Examples
:::{.example}
## `lib.fixedPoints.composeManyExtensions` usage example without `lib.extends`
```nix
let
# Each overlay function has 'final' and 'prev' as arguments.
overlayA = final: prev: {
b = final.c; # The final value of c after overlayB
c = 3;
};
overlayB = final: prev: {
c = 10;
cPrev = prev.c; # The value of c before overlayB
};
extensions = composeManyExtensions [ overlayA overlayB ];
# Calculate the fixed point of all composed overlays.
# With an empty attribute set as the initial value.
fixedpoint = lib.fix (final: extensions final {});
in fixedpoint
=>
{
b = 10;
c = 10;
cPrev = 3;
}
```
:::
:::{.example}
## `lib.fixedPoints.composeManyExtensions` usage example with `lib.extends`
If the initial attribute set should be part of the fixed point, `lib.extends` can be used to apply the composed overlays.
```nix
let
# The first overlay function. Is
original = final: { a = 1; };
# Each overlay function has 'final' and 'prev' as arguments.
overlayA = final: prev: { b = final.c; c = 3; };
overlayB = final: prev: { c = 10; cPrev = prev.c; };
extensions = composeManyExtensions [ overlayA overlayB ];
# Caluculate the fixed point of all composed overlays.
fixedpoint = lib.fix (lib.extends extensions original );
in fixedpoint
=>
{
a = 1;
b = 10;
c = 10;
cPrev = 3;
}
```
:::
*/
composeManyExtensions =
lib.foldr (x: y: composeExtensions x y) (final: prev: {});
Expand All @@ -421,17 +485,17 @@ rec {
Create an overridable, recursive attribute set. For example:
```
nix-repl> obj = makeExtensible (self: { })
nix-repl> obj = makeExtensible (final: { })
nix-repl> obj
{ __unfix__ = «lambda»; extend = «lambda»; }
nix-repl> obj = obj.extend (self: super: { foo = "foo"; })
nix-repl> obj = obj.extend (final: prev: { foo = "foo"; })
nix-repl> obj
{ __unfix__ = «lambda»; extend = «lambda»; foo = "foo"; }
nix-repl> obj = obj.extend (self: super: { foo = super.foo + " + "; bar = "bar"; foobar = self.foo + self.bar; })
nix-repl> obj = obj.extend (final: prev: { foo = prev.foo + " + "; bar = "bar"; foobar = final.foo + final.bar; })
nix-repl> obj
{ __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; }
Expand Down

0 comments on commit 126a045

Please sign in to comment.