extends
lib.fixedPoints.extends
Extend a function using an overlay.
Overlays allow modifying and extending fixed-point functions, specifically ones returning attribute sets. A fixed-point function is a function which is intended to be evaluated by passing the result of itself as the argument. This is possible due to Nix's lazy evaluation.
A fixed-point function returning an attribute set has the form
final: { # attributes }
where final
refers to the lazily evaluated attribute set returned by the fixed-point function.
An overlay to such a fixed-point function has the form
final: prev: { # attributes }
where prev
refers to the result of the original function to final
, and final
is the result of the composition of the overlay and the original function.
Applying an overlay is done with extends
:
let
f = final: { # attributes };
overlay = final: prev: { # attributes };
in extends overlay f;
To get the value of final
, use lib.fix
:
let
f = final: { # attributes };
overlay = final: prev: { # attributes };
g = extends overlay f;
in fix g
The argument to the given fixed-point function after applying an overlay will not refer to its own return value, but rather to the value after evaluating the overlay function.
The given fixed-point function is called with a separate argument than if it was evaluated with lib.fix
.
Extend a fixed-point function with an overlay
Define a fixed-point function f
that expects its own output as the argument final
:
f = final: {
# Constant value a
a = 1;
# b depends on the final value of a, available as final.a
b = final.a + 2;
}
Evaluate this using lib.fix
to get the final result:
fix f
=> { a = 1; b = 3; }
An overlay represents a modification or extension of such a fixed-point function. Here's an example of an overlay:
overlay = final: prev: {
# Modify the previous value of a, available as prev.a
a = prev.a + 10;
# Extend the attribute set with c, letting it depend on the final values of a and b
c = final.a + final.b;
}
Use extends overlay f
to apply the overlay to the fixed-point function f
.
This produces a new fixed-point function g
with the combined behavior of f
and overlay
:
g = extends overlay f
The result is a function, so we can't print it directly, but it's the same as:
g' = final: {
# The constant from f, but changed with the overlay
a = 1 + 10;
# Unchanged from f
b = final.a + 2;
# Extended in the overlay
c = final.a + final.b;
}
Evaluate this using lib.fix
again to get the final result:
fix g
=> { a = 11; b = 13; c = 24; }
Inputs
overlay
-
The overlay to apply to the fixed-point function
f
-
The fixed-point function
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
lib.fixedPoints.extends
usage example
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; }