nix-super/tests/functional/repl/doc-functor.nix

102 lines
2.6 KiB
Nix
Raw Permalink Normal View History

2024-08-15 13:29:59 +03:00
rec {
/**
Look, it's just like a function!
*/
multiply = p: q: p * q;
multiplier = {
factor = 2;
/**
Multiply the argument by the factor stored in the factor attribute.
*/
__functor = self: x: x * self.factor;
};
doubler = {
description = "bla";
/**
Multiply by two. This doc probably won't be rendered because the
returned partial application won't have any reference to this location;
only pointing to the second lambda in the multiply function.
*/
__functor = self: multiply 2;
};
makeOverridable = f: {
/**
This is a function that can be overridden.
*/
__functor = self: f;
override = throw "not implemented";
};
/**
Compute x^2
*/
square = x: x * x;
helper = makeOverridable square;
# Somewhat analogous to the Nixpkgs makeOverridable function.
makeVeryOverridable = f: {
/**
This is a function that can be overridden.
*/
__functor = self: arg: f arg // { override = throw "not implemented"; overrideAttrs = throw "not implemented"; };
override = throw "not implemented";
};
helper2 = makeVeryOverridable square;
# The RFC might be ambiguous here. The doc comment from makeVeryOverridable
# is "inner" in terms of values, but not inner in terms of expressions.
# Returning the following attribute comment might be allowed.
# TODO: I suppose we could look whether the attribute value expression
# contains a doc, and if not, return the attribute comment anyway?
/**
Compute x^3
*/
lib.helper3 = makeVeryOverridable (x: x * x * x);
/**
Compute x^3...
*/
helper3 = makeVeryOverridable (x: x * x * x);
# ------
# getDoc traverses a potentially infinite structure in case of __functor, so
# we need to test with recursive inputs and diverging inputs.
recursive = {
/**
This looks bad, but the docs are ok because of the eta expansion.
*/
__functor = self: x: self x;
};
recursive2 = {
/**
Docs probably won't work in this case, because the "partial" application
of self results in an infinite recursion.
*/
__functor = self: self.__functor self;
};
diverging = let
/**
Docs probably won't work in this case, because the "partial" application
of self results in an diverging computation that causes a stack overflow.
It's not an infinite recursion because each call is different.
This must be handled by the documentation retrieval logic, as it
reimplements the __functor invocation to be partial.
*/
f = x: {
__functor = self: (f (x + 1));
};
in f null;
}