Functors combine functions and attribute sets
A functor is a polymorphic data type that can represent both a
lambda function (x: x) and an attribute set ({ key = value; }).
This means that the Atribute set can hold data in the form of attributes.
And also be a lambda function that can operate on that data.
-> The lambda function can access the attributes of the attribute set often called self.
In the following example, build is both an attribute set and a lambda.
__functor is a reserved attribute name that turns the attribute set build into a functor.
{
build = {
foo = 1;
__functor = self: _arg: self.foo;
};
}
The attribute set build can now be used as a lambda via function application.
nix-repl> build "linux"
=> 1
But at the same time build is still an Attribute set.
nix-repl> build
=> { __functor = «lambda»; foo = 1; }
Functors find practical applications including some in nixpkgs:
lib.makeOverridablelib.setFunctionArgslib.mirrorFunctionArgslib.types and lib.options(Noogle opinion)
The use of functor should be avoided and is often unnecessary.
Using them can add up in complexity and makes is hard to learn and maintain a certain piece of code.