mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-09-19 03:29:17 +03:00
Merge pull request #298680 from gvolpe/lib/transposeMap
lib/attrsets: add mapCartesianProduct function
This commit is contained in:
commit
e00a40a257
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
inherit (builtins) head length;
|
inherit (builtins) head length;
|
||||||
inherit (lib.trivial) mergeAttrs warn;
|
inherit (lib.trivial) isInOldestRelease mergeAttrs warn warnIf;
|
||||||
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
|
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
|
||||||
inherit (lib.lists) foldr foldl' concatMap elemAt all partition groupBy take foldl;
|
inherit (lib.lists) foldr foldl' concatMap elemAt all partition groupBy take foldl;
|
||||||
in
|
in
|
||||||
@ -885,15 +885,15 @@ rec {
|
|||||||
# Type
|
# Type
|
||||||
|
|
||||||
```
|
```
|
||||||
cartesianProductOfSets :: AttrSet -> [AttrSet]
|
cartesianProduct :: AttrSet -> [AttrSet]
|
||||||
```
|
```
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
:::{.example}
|
:::{.example}
|
||||||
## `lib.attrsets.cartesianProductOfSets` usage example
|
## `lib.attrsets.cartesianProduct` usage example
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
|
cartesianProduct { a = [ 1 2 ]; b = [ 10 20 ]; }
|
||||||
=> [
|
=> [
|
||||||
{ a = 1; b = 10; }
|
{ a = 1; b = 10; }
|
||||||
{ a = 1; b = 20; }
|
{ a = 1; b = 20; }
|
||||||
@ -904,7 +904,7 @@ rec {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
*/
|
*/
|
||||||
cartesianProductOfSets =
|
cartesianProduct =
|
||||||
attrsOfLists:
|
attrsOfLists:
|
||||||
foldl' (listOfAttrs: attrName:
|
foldl' (listOfAttrs: attrName:
|
||||||
concatMap (attrs:
|
concatMap (attrs:
|
||||||
@ -913,6 +913,40 @@ rec {
|
|||||||
) [{}] (attrNames attrsOfLists);
|
) [{}] (attrNames attrsOfLists);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the result of function f applied to the cartesian product of attribute set value combinations.
|
||||||
|
Equivalent to using cartesianProduct followed by map.
|
||||||
|
|
||||||
|
# Inputs
|
||||||
|
|
||||||
|
`f`
|
||||||
|
|
||||||
|
: A function, given an attribute set, it returns a new value.
|
||||||
|
|
||||||
|
`attrsOfLists`
|
||||||
|
|
||||||
|
: Attribute set with attributes that are lists of values
|
||||||
|
|
||||||
|
# Type
|
||||||
|
|
||||||
|
```
|
||||||
|
mapCartesianProduct :: (AttrSet -> a) -> AttrSet -> [a]
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `lib.attrsets.mapCartesianProduct` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
mapCartesianProduct ({a, b}: "${a}-${b}") { a = [ "1" "2" ]; b = [ "3" "4" ]; }
|
||||||
|
=> [ "1-3" "1-4" "2-3" "2-4" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
*/
|
||||||
|
mapCartesianProduct = f: attrsOfLists: map f (cartesianProduct 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`.
|
||||||
|
|
||||||
@ -1999,4 +2033,8 @@ rec {
|
|||||||
# DEPRECATED
|
# DEPRECATED
|
||||||
zip = warn
|
zip = warn
|
||||||
"lib.zip is a deprecated alias of lib.zipAttrsWith." zipAttrsWith;
|
"lib.zip is a deprecated alias of lib.zipAttrsWith." zipAttrsWith;
|
||||||
|
|
||||||
|
# DEPRECATED
|
||||||
|
cartesianProductOfSets = warnIf (isInOldestRelease 2405)
|
||||||
|
"lib.cartesianProductOfSets is a deprecated alias of lib.cartesianProduct." cartesianProduct;
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,8 @@ let
|
|||||||
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
||||||
recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput
|
recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput
|
||||||
getBin getLib getDev getMan chooseDevOutputs zipWithNames zip
|
getBin getLib getDev getMan chooseDevOutputs zipWithNames zip
|
||||||
recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets
|
recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets
|
||||||
updateManyAttrsByPath;
|
mapCartesianProduct updateManyAttrsByPath;
|
||||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||||
concatMap flatten remove findSingle findFirst any all count
|
concatMap flatten remove findSingle findFirst any all count
|
||||||
optional optionals toList range replicate partition zipListsWith zipLists
|
optional optionals toList range replicate partition zipListsWith zipLists
|
||||||
|
@ -1688,16 +1688,32 @@ rec {
|
|||||||
## `lib.lists.crossLists` usage example
|
## `lib.lists.crossLists` usage example
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
|
crossLists (x: y: "${toString x}${toString y}") [[1 2] [3 4]]
|
||||||
=> [ "13" "14" "23" "24" ]
|
=> [ "13" "14" "23" "24" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The following function call is equivalent to the one deprecated above:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
mapCartesianProduct (x: "${toString x.a}${toString x.b}") { a = [1 2]; b = [3 4]; }
|
||||||
|
=> [ "13" "14" "23" "24" ]
|
||||||
|
```
|
||||||
:::
|
:::
|
||||||
*/
|
*/
|
||||||
crossLists = warn
|
crossLists = warn
|
||||||
"lib.crossLists is deprecated, use lib.cartesianProductOfSets instead."
|
''lib.crossLists is deprecated, use lib.mapCartesianProduct instead.
|
||||||
(f: foldl (fs: args: concatMap (f: map f args) fs) [f]);
|
|
||||||
|
|
||||||
|
For example, the following function call:
|
||||||
|
|
||||||
|
nix-repl> lib.crossLists (x: y: x+y) [[1 2] [3 4]]
|
||||||
|
[ 4 5 5 6 ]
|
||||||
|
|
||||||
|
Can now be replaced by the following one:
|
||||||
|
|
||||||
|
nix-repl> lib.mapCartesianProduct ({x,y}: x+y) { x = [1 2]; y = [3 4]; }
|
||||||
|
[ 4 5 5 6 ]
|
||||||
|
''
|
||||||
|
(f: foldl (fs: args: concatMap (f: map f args) fs) [f]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Remove duplicate elements from the `list`. O(n^2) complexity.
|
Remove duplicate elements from the `list`. O(n^2) complexity.
|
||||||
|
@ -33,7 +33,7 @@ let
|
|||||||
boolToString
|
boolToString
|
||||||
callPackagesWith
|
callPackagesWith
|
||||||
callPackageWith
|
callPackageWith
|
||||||
cartesianProductOfSets
|
cartesianProduct
|
||||||
cli
|
cli
|
||||||
composeExtensions
|
composeExtensions
|
||||||
composeManyExtensions
|
composeManyExtensions
|
||||||
@ -71,10 +71,10 @@ let
|
|||||||
makeIncludePath
|
makeIncludePath
|
||||||
makeOverridable
|
makeOverridable
|
||||||
mapAttrs
|
mapAttrs
|
||||||
|
mapCartesianProduct
|
||||||
matchAttrs
|
matchAttrs
|
||||||
mergeAttrs
|
mergeAttrs
|
||||||
meta
|
meta
|
||||||
mkOption
|
|
||||||
mod
|
mod
|
||||||
nameValuePair
|
nameValuePair
|
||||||
optionalDrvAttr
|
optionalDrvAttr
|
||||||
@ -117,7 +117,6 @@ let
|
|||||||
expr = (builtins.tryEval expr).success;
|
expr = (builtins.tryEval expr).success;
|
||||||
expected = true;
|
expected = true;
|
||||||
};
|
};
|
||||||
testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr);
|
|
||||||
|
|
||||||
testSanitizeDerivationName = { name, expected }:
|
testSanitizeDerivationName = { name, expected }:
|
||||||
let
|
let
|
||||||
@ -1415,7 +1414,7 @@ runTests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testToPrettyMultiline = {
|
testToPrettyMultiline = {
|
||||||
expr = mapAttrs (const (generators.toPretty { })) rec {
|
expr = mapAttrs (const (generators.toPretty { })) {
|
||||||
list = [ 3 4 [ false ] ];
|
list = [ 3 4 [ false ] ];
|
||||||
attrs = { foo = null; bar.foo = "baz"; };
|
attrs = { foo = null; bar.foo = "baz"; };
|
||||||
newlinestring = "\n";
|
newlinestring = "\n";
|
||||||
@ -1429,7 +1428,7 @@ runTests {
|
|||||||
there
|
there
|
||||||
test'';
|
test'';
|
||||||
};
|
};
|
||||||
expected = rec {
|
expected = {
|
||||||
list = ''
|
list = ''
|
||||||
[
|
[
|
||||||
3
|
3
|
||||||
@ -1467,13 +1466,10 @@ runTests {
|
|||||||
expected = "«foo»";
|
expected = "«foo»";
|
||||||
};
|
};
|
||||||
|
|
||||||
testToPlist =
|
testToPlist = {
|
||||||
let
|
|
||||||
deriv = derivation { name = "test"; builder = "/bin/sh"; system = "aarch64-linux"; };
|
|
||||||
in {
|
|
||||||
expr = mapAttrs (const (generators.toPlist { })) {
|
expr = mapAttrs (const (generators.toPlist { })) {
|
||||||
value = {
|
value = {
|
||||||
nested.values = rec {
|
nested.values = {
|
||||||
int = 42;
|
int = 42;
|
||||||
float = 0.1337;
|
float = 0.1337;
|
||||||
bool = true;
|
bool = true;
|
||||||
@ -1686,17 +1682,17 @@ runTests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testCartesianProductOfEmptySet = {
|
testCartesianProductOfEmptySet = {
|
||||||
expr = cartesianProductOfSets {};
|
expr = cartesianProduct {};
|
||||||
expected = [ {} ];
|
expected = [ {} ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testCartesianProductOfOneSet = {
|
testCartesianProductOfOneSet = {
|
||||||
expr = cartesianProductOfSets { a = [ 1 2 3 ]; };
|
expr = cartesianProduct { a = [ 1 2 3 ]; };
|
||||||
expected = [ { a = 1; } { a = 2; } { a = 3; } ];
|
expected = [ { a = 1; } { a = 2; } { a = 3; } ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testCartesianProductOfTwoSets = {
|
testCartesianProductOfTwoSets = {
|
||||||
expr = cartesianProductOfSets { a = [ 1 ]; b = [ 10 20 ]; };
|
expr = cartesianProduct { a = [ 1 ]; b = [ 10 20 ]; };
|
||||||
expected = [
|
expected = [
|
||||||
{ a = 1; b = 10; }
|
{ a = 1; b = 10; }
|
||||||
{ a = 1; b = 20; }
|
{ a = 1; b = 20; }
|
||||||
@ -1704,12 +1700,12 @@ runTests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
testCartesianProductOfTwoSetsWithOneEmpty = {
|
testCartesianProductOfTwoSetsWithOneEmpty = {
|
||||||
expr = cartesianProductOfSets { a = [ ]; b = [ 10 20 ]; };
|
expr = cartesianProduct { a = [ ]; b = [ 10 20 ]; };
|
||||||
expected = [ ];
|
expected = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testCartesianProductOfThreeSets = {
|
testCartesianProductOfThreeSets = {
|
||||||
expr = cartesianProductOfSets {
|
expr = cartesianProduct {
|
||||||
a = [ 1 2 3 ];
|
a = [ 1 2 3 ];
|
||||||
b = [ 10 20 30 ];
|
b = [ 10 20 30 ];
|
||||||
c = [ 100 200 300 ];
|
c = [ 100 200 300 ];
|
||||||
@ -1753,6 +1749,30 @@ runTests {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testMapCartesianProductOfOneSet = {
|
||||||
|
expr = mapCartesianProduct ({a}: a * 2) { a = [ 1 2 3 ]; };
|
||||||
|
expected = [ 2 4 6 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testMapCartesianProductOfTwoSets = {
|
||||||
|
expr = mapCartesianProduct ({a,b}: a + b) { a = [ 1 ]; b = [ 10 20 ]; };
|
||||||
|
expected = [ 11 21 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testMapCartesianProcutOfTwoSetsWithOneEmpty = {
|
||||||
|
expr = mapCartesianProduct (x: x.a + x.b) { a = [ ]; b = [ 10 20 ]; };
|
||||||
|
expected = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testMapCartesianProductOfThreeSets = {
|
||||||
|
expr = mapCartesianProduct ({a,b,c}: a + b + c) {
|
||||||
|
a = [ 1 2 3 ];
|
||||||
|
b = [ 10 20 30 ];
|
||||||
|
c = [ 100 200 300 ];
|
||||||
|
};
|
||||||
|
expected = [ 111 211 311 121 221 321 131 231 331 112 212 312 122 222 322 132 232 332 113 213 313 123 223 323 133 233 333 ];
|
||||||
|
};
|
||||||
|
|
||||||
# The example from the showAttrPath documentation
|
# The example from the showAttrPath documentation
|
||||||
testShowAttrPathExample = {
|
testShowAttrPathExample = {
|
||||||
expr = showAttrPath [ "foo" "10" "bar" ];
|
expr = showAttrPath [ "foo" "10" "bar" ];
|
||||||
|
@ -284,7 +284,7 @@ in
|
|||||||
in
|
in
|
||||||
# We will generate every possible pair of WM and DM.
|
# We will generate every possible pair of WM and DM.
|
||||||
concatLists (
|
concatLists (
|
||||||
builtins.map
|
lib.mapCartesianProduct
|
||||||
({dm, wm}: let
|
({dm, wm}: let
|
||||||
sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}";
|
sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}";
|
||||||
script = xsession dm wm;
|
script = xsession dm wm;
|
||||||
@ -312,7 +312,7 @@ in
|
|||||||
providedSessions = [ sessionName ];
|
providedSessions = [ sessionName ];
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
(cartesianProductOfSets { dm = dms; wm = wms; })
|
{ dm = dms; wm = wms; }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
|
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
|
||||||
testCombinations = pkgs.lib.cartesianProductOfSets {
|
testCombinations = pkgs.lib.cartesianProduct {
|
||||||
predictable = [true false];
|
predictable = [true false];
|
||||||
withNetworkd = [true false];
|
withNetworkd = [true false];
|
||||||
systemdStage1 = [true false];
|
systemdStage1 = [true false];
|
||||||
|
@ -63,16 +63,15 @@ in stdenv.mkDerivation {
|
|||||||
runHook postCheck
|
runHook postCheck
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = {
|
meta = with lib; {
|
||||||
description = "Sandboxed execution environment";
|
description = "Sandboxed execution environment";
|
||||||
homepage = "https://github.com/solo5/solo5";
|
homepage = "https://github.com/solo5/solo5";
|
||||||
license = lib.licenses.isc;
|
license = licenses.isc;
|
||||||
maintainers = with lib.maintainers; [ ehmry ];
|
maintainers = [ maintainers.ehmry ];
|
||||||
platforms = builtins.map ({arch, os}: "${arch}-${os}")
|
platforms = mapCartesianProduct ({ arch, os }: "${arch}-${os}") {
|
||||||
(lib.cartesianProductOfSets {
|
arch = [ "aarch64" "x86_64" ];
|
||||||
arch = [ "aarch64" "x86_64" ];
|
os = [ "freebsd" "genode" "linux" "openbsd" ];
|
||||||
os = [ "freebsd" "genode" "linux" "openbsd" ];
|
};
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,13 @@ let
|
|||||||
'');
|
'');
|
||||||
in
|
in
|
||||||
builtins.listToAttrs (
|
builtins.listToAttrs (
|
||||||
map
|
lib.mapCartesianProduct texTest
|
||||||
texTest
|
{
|
||||||
(lib.attrsets.cartesianProductOfSets {
|
|
||||||
tex = [ "xelatex" "lualatex" ];
|
tex = [ "xelatex" "lualatex" ];
|
||||||
fonttype = [ "ttf" "otf" ];
|
fonttype = [ "ttf" "otf" ];
|
||||||
package = [ "junicode" ];
|
package = [ "junicode" ];
|
||||||
file = [ ./test.tex ];
|
file = [ ./test.tex ];
|
||||||
})
|
}
|
||||||
++
|
++
|
||||||
[
|
[
|
||||||
(texTest {
|
(texTest {
|
||||||
|
@ -9,9 +9,8 @@ let
|
|||||||
palette = [ "Frappe" "Latte" "Macchiato" "Mocha" ];
|
palette = [ "Frappe" "Latte" "Macchiato" "Mocha" ];
|
||||||
color = [ "Blue" "Dark" "Flamingo" "Green" "Lavender" "Light" "Maroon" "Mauve" "Peach" "Pink" "Red" "Rosewater" "Sapphire" "Sky" "Teal" "Yellow" ];
|
color = [ "Blue" "Dark" "Flamingo" "Green" "Lavender" "Light" "Maroon" "Mauve" "Peach" "Pink" "Red" "Rosewater" "Sapphire" "Sky" "Teal" "Yellow" ];
|
||||||
};
|
};
|
||||||
product = lib.attrsets.cartesianProductOfSets dimensions;
|
|
||||||
variantName = { palette, color }: (lib.strings.toLower palette) + color;
|
variantName = { palette, color }: (lib.strings.toLower palette) + color;
|
||||||
variants = map variantName product;
|
variants = lib.mapCartesianProduct variantName dimensions;
|
||||||
in
|
in
|
||||||
stdenvNoCC.mkDerivation rec {
|
stdenvNoCC.mkDerivation rec {
|
||||||
pname = "catppuccin-cursors";
|
pname = "catppuccin-cursors";
|
||||||
|
@ -7,14 +7,13 @@ let
|
|||||||
thickness = [ "" "Slim_" ]; # Thick or slim edges.
|
thickness = [ "" "Slim_" ]; # Thick or slim edges.
|
||||||
handedness = [ "" "LH_" ]; # Right- or left-handed.
|
handedness = [ "" "LH_" ]; # Right- or left-handed.
|
||||||
};
|
};
|
||||||
product = lib.cartesianProductOfSets dimensions;
|
|
||||||
variantName =
|
variantName =
|
||||||
{ color, opacity, thickness, handedness }:
|
{ color, opacity, thickness, handedness }:
|
||||||
"${handedness}${opacity}${thickness}${color}";
|
"${handedness}${opacity}${thickness}${color}";
|
||||||
variants =
|
variants =
|
||||||
# (The order of this list is already good looking enough to show in the
|
# (The order of this list is already good looking enough to show in the
|
||||||
# meta.longDescription.)
|
# meta.longDescription.)
|
||||||
map variantName product;
|
lib.mapCartesianProduct variantName dimensions;
|
||||||
in
|
in
|
||||||
stdenvNoCC.mkDerivation rec {
|
stdenvNoCC.mkDerivation rec {
|
||||||
pname = "comixcursors";
|
pname = "comixcursors";
|
||||||
|
@ -70,7 +70,7 @@ stdenv.mkDerivation rec {
|
|||||||
maintainers = [ maintainers.sternenseemann ];
|
maintainers = [ maintainers.sternenseemann ];
|
||||||
homepage = "https://github.com/mirage/ocaml-freestanding";
|
homepage = "https://github.com/mirage/ocaml-freestanding";
|
||||||
platforms = builtins.map ({ arch, os }: "${arch}-${os}")
|
platforms = builtins.map ({ arch, os }: "${arch}-${os}")
|
||||||
(cartesianProductOfSets {
|
(cartesianProduct {
|
||||||
arch = [ "aarch64" "x86_64" ];
|
arch = [ "aarch64" "x86_64" ];
|
||||||
os = [ "linux" ];
|
os = [ "linux" ];
|
||||||
} ++ [
|
} ++ [
|
||||||
|
Loading…
Reference in New Issue
Block a user