diff options
author | Shea Levy <shea@shealevy.com> | 2017-09-28 18:10:50 -0400 |
---|---|---|
committer | Shea Levy <shea@shealevy.com> | 2017-09-28 18:10:50 -0400 |
commit | c3af1210b4c5d7ef380e75add463b37574fdcc8b (patch) | |
tree | 0e97578072574d3c971c5c225289f13118e80a50 /lib/fixed-points.nix | |
parent | 49f175cd0c80a39e1d05fc687c4a2a40e0aba58c (diff) | |
parent | dbd500937644c2deae4a2c7a59f4a11a006bf1d0 (diff) |
Merge branch 'improved-make-overridable' of git://github.com/ElvishJerricco/nixpkgs
Diffstat (limited to 'lib/fixed-points.nix')
-rw-r--r-- | lib/fixed-points.nix | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/lib/fixed-points.nix b/lib/fixed-points.nix index 13e053b5aa7d..2526360c111d 100644 --- a/lib/fixed-points.nix +++ b/lib/fixed-points.nix @@ -72,8 +72,34 @@ rec { # Same as `makeExtensible` but the name of the extending attribute is # customized. - makeExtensibleWithCustomName = extenderName: rattrs: - fix' rattrs // { - ${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs); - }; + makeExtensibleWithCustomName = extenderName: f: makeExtensibleWithInterface + (fixedPoint: extend: fixedPoint // { ${extenderName} = ext: extend (_: ext); }) + (_: f); + + # A version of `makeExtensible` that allows the function being fixed + # to return a different interface than the interface returned to the + # user. Along with `self` and `super` views of the internal + # interface, a `self` view of the output interface is also + # provided. `extend` is not added to the output by default. This is + # the job of the interface. + # + # nix-repl> foo = {a, b}: {c = a + b;} + # + # nix-repl> interface = {args, val, ...}: extend: val // {inherit extend;} + # + # nix-repl> obj = makeExtensibleWithInterface interface (output: self: { args = {a = 1; b = 2;}; val = foo self.args; }) + # + # nix-repl> obj.c + # 3 + # + # nix-repl> obj = obj.extend (output: self: super: { args = super.args // { b = output.d; }; }) + # + # nix-repl> obj = obj.extend (output: self: super: { val = super.val // { d = 10; }; }) + # + # nix-repl> { inherit (obj) c d; } + # { c = 11; d = 10; } + makeExtensibleWithInterface = interface: f: let i = interface + (fix' (f i)) + (fext: makeExtensibleWithInterface interface (i': (extends (fext i') (f i')))); + in i; } |