[Nix-dev] An issue regarding the default parameters of a function
Harald van Dijk
harald at gigawatt.nl
Fri Feb 12 13:03:05 CET 2016
On 12/02/2016 12:11, Sergey Mironov wrote:
> Hi. I have an issue regarding the combination of two Nix features:
> default parameters ( f = {arg ? def } : ...) and arbitrary length
> parameters (f = args@{arg, ...} : ...). It looks like they doesn't
> work together silently. Here is the example from my code. I'd like the
> function make-nk-parser to tweak some of it's arguments and pass them
> downstream to the makeHaskell function. In particular, I want it to
> add 'nk' to the list of dependencies or make it the only dependency.
>
>
> make-nk-parser = args@{buildDepends ? [], ...} :
> makeHaskell (args // {
> pname = "nk-parser";
> buildDepends = args.buildDepends ++ [nk];
> isExecutable = true;
> });
>
> Unfortunately, this code doesn't work.
Right. This only makes buildDepends [], not args.buildDepends.
So you can simply use
make-nk-parser = args@{buildDepends ? [], ...} :
makeHaskell (args // {
pname = "nk-parser";
buildDepends = buildDepends ++ [nk];
isExecutable = true;
});
In buildDepends ++ [nk] here, buildDepends still refers to the argument,
not the attribute, because the rec keyword was not used.
If you really need default arguments accessible from args, if you're
using args somewhere else where you cannot control its buildDepends from
being accessed, you can use // to combine default and explicitly
specified arguments:
make-nk-parser = explicitArgs : let
defaultArgs = { buildDepends = []; };
args = defaultArgs // explicitArgs;
in makeHaskell (args // {
pname = "nk-parser";
buildDepends = args.buildDepends ++ [nk];
isExecutable = true;
});
Both of these might be easier to maintain than the workaround you've
come up with, although yours is of course perfectly valid too.
Cheers,
Harald van Dijk
More information about the nix-dev
mailing list