forked from auxolotl/labs
83 lines
2 KiB
Nix
83 lines
2 KiB
Nix
let
|
|
files = [
|
|
./attrs
|
|
./bools
|
|
./dag
|
|
./errors
|
|
./fp
|
|
./generators
|
|
./importers
|
|
./licenses
|
|
./lists
|
|
./math
|
|
./modules
|
|
./numbers
|
|
./options
|
|
./packages
|
|
./paths
|
|
./points
|
|
./strings
|
|
./types
|
|
./versions
|
|
];
|
|
|
|
libs = builtins.map (f: import f) files;
|
|
|
|
## Calculate the fixed point of a function. This will evaluate the function `f`
|
|
## until its result settles (or Nix's recursion limit is reached). This allows
|
|
## us to define recursive functions without worrying about the order of their
|
|
## definitions.
|
|
##
|
|
## @type (a -> a) -> a
|
|
fix =
|
|
f:
|
|
let
|
|
x = f x;
|
|
in
|
|
x;
|
|
|
|
## Merge two attribute sets recursively until a given predicate returns true.
|
|
## Any values that are _not_ attribute sets will be overridden with the value
|
|
## from `y` first if it exists and then `x` otherwise.
|
|
##
|
|
## @type Attrs a b c => (String -> Any -> Any -> Bool) -> a -> b -> c
|
|
mergeAttrsRecursiveUntil =
|
|
predicate: x: y:
|
|
let
|
|
process =
|
|
path:
|
|
builtins.zipAttrsWith (
|
|
name: values:
|
|
let
|
|
currentPath = path ++ [ name ];
|
|
isSingleValue = builtins.length values == 1;
|
|
isComplete = predicate currentPath (builtins.elemAt values 1) (builtins.elemAt values 0);
|
|
in
|
|
if isSingleValue || isComplete then builtins.elemAt values 0 else process currentPath values
|
|
);
|
|
in
|
|
process [ ] [
|
|
x
|
|
y
|
|
];
|
|
|
|
## Merge two attribute sets recursively. Any values that are _not_ attribute sets
|
|
## will be overridden with the value from `y` first if it exists and then `x`
|
|
## otherwise.
|
|
##
|
|
## @type Attrs a b c => a -> b -> c
|
|
mergeAttrsRecursive = mergeAttrsRecursiveUntil (
|
|
path: x: y:
|
|
!(builtins.isAttrs x && builtins.isAttrs y)
|
|
);
|
|
|
|
lib = fix (
|
|
self:
|
|
let
|
|
merge = acc: create: mergeAttrsRecursive acc (create self);
|
|
in
|
|
builtins.foldl' merge { } libs
|
|
);
|
|
in
|
|
lib.points.withExtend (lib.fp.const lib)
|