gpt4 book ai didi

functional-programming - 尼克斯药丸 14 : How to make callPackage overridable?

转载 作者:行者123 更新时间:2023-12-03 22:01:06 25 4
gpt4 key购买 nike

我在理解时遇到问题 Nix Pill 14 .作者提供makeOverridable ,然后挑战用户将其与 callPackage 集成. makeOverridabledefault.nix提供如下,其中makeOverridable在文件中 lib.nix , 和 callPackage在文件中 default.nix :

# file: lib.nix

rec {
makeOverridable = f: origArgs:
let
origRes = f origArgs;
in
origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
}
# file: default.nix

let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = callPackage ./graphviz.nix { gdSupport = false; };
};
in pkgs

这是我想出的:
# file: default.nix (my implementation)

let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let
f = import path;
origRes = f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
in
origRes // { override = newArgs: callPackage f (overrides // newArgs); };
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = import ./hello.nix {};
graphviz = import ./graphviz.nix {};
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs

我想我对这里发生的事情有一个根本的误解。您能否提供正确的实现并解释我做错了什么?

编辑:我设法让它工作,但是,它仍然不是递归的。
# file: default.nix

let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let
f = import path;
origArgs = f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
makeOverridable = { override = newArgs: (origArgs // newArgs); };
in
origArgs // makeOverridable;
pkgs = with nixpkgs; rec {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs

编辑2:
# file: default.nix

let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
makeOverridable = f: origArgs:
let origRes = f origArgs;
in origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
callPackage1 = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
callPackage = makeOverridable callPackage1;
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs

解决方案:
# file: default.nix

let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
makeOverridable = f: origArgs:
let origRes = f origArgs;
in origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
callPackage1 = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
callPackage = path: makeOverridable (callPackage1 path);
pkgs = with nixpkgs; rec {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
local_graphviz = callPackage ./graphviz.nix { };
graphvizCore = local_graphviz.override { gdSupport = false; };
graphvizCore2 = graphvizCore.override { gdSupport = false; };
};
in pkgs

最佳答案

makeOverridable使用 Nix Pills 中的定义之一正确定义,您可以将其视为高阶函数:它采用名为 f 的普通函数,并将其更改为一个新函数,其结果可以被覆盖。

假设您已经有一个名为 callPackage1 的函数,你可以像这样制作一个可覆盖的版本:

rec {
callPackage1 = ...;
callPackage = makeOverridable callPackage1;
}

编辑 1:

其实, callPackage1需要一个路径来返回 makeOverridable 期望的函数类型(一个接受集合并返回一个对象的函数,我们可以向其添加覆盖 attribute )。所以让我们试试 callPackage 的这个定义:
callPackage = path: makeOverridable (callPackage1 path);

关于functional-programming - 尼克斯药丸 14 : How to make callPackage overridable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59510870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com