`let ... in rec {}` vs `import ./funcs.nix`

Hi,

I am getting this error value is a function while a set was expected. I am not too sure what is going on. I have some experience with Haskell so I want to assume it has something to do with lazy evaluation. Although, I am not familiar enough with the nix language to be sure. I added some code snippets to provide some context for the error. Any help or guidance is appreciated.

# some_module.nix
{inputs, ... }:
let
  util = import ./utils.nix;
# vs
  createEntry = arg: "some entry ${arg}";
  genEntry = arg: (createEntry arg);
in
rec
{
# works
  option.expectingList = [ (genEntry "foo") ];
# does not work
  option.expectingList = [ (util.genEntry "foo") ];
}
# utils.nix
{ ... }:
{
  createEntry = arg: "some entry ${arg}";
  genEntry = arg: (createEntry arg);
}

The expression stored in utils.nix is a function (you can tell because it starts with { ... }:).

Therefore, the value of import ./utils.nix is a function.

Therefore, in the does-not-work case, the value of the util variable is a function.

So when you ask for util.genEntry, you are asking for an attribute of a function. But Nix only knows how to get attributes from sets. Thus, value is a function while a set was expected.

If you aren’t using that { ... }: parameter, you can remove it and then your code will work. Alternatively, if you are using it, you can give it an argument via util = import ./utils.nix { ... }; or something similar.

2 Likes

Hi rhendric,

Thank you for the clarifying what was happening and providing a way to resolve the error. I really appreciate the help.

For others, here is a an updated snippet that works implementing what rhendric said:

# some_module.nix
{inputs, ... }:
let
# with input
  util = import ./utils.nix { inherit inputs; };
# without
  util = import ./utils.nix;
in
rec
{
  option.expectingList = [ (util.genEntry "foo") ];
}

With input:

# utils.nix
{ inputs }:
rec {
  createEntry = arg: "some entry ${inputs}/foo.txt ${arg}";
  genEntry = arg: (createEntry arg);
}

Without input:

# utils.nix
rec {
  createEntry = arg: "some entry ${arg}";
  genEntry = arg: (createEntry arg);
}