From 08021dd8253b6fa6ab625cd925e4bd3f09f1d8b4 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 11 Jul 2017 21:33:26 -0400 Subject: [PATCH] Added `makeExtensibleWithInterface` --- lib/fixed-points.nix | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/fixed-points.nix b/lib/fixed-points.nix index a11b5a6f4bd..5039a45cc3f 100644 --- a/lib/fixed-points.nix +++ b/lib/fixed-points.nix @@ -71,8 +71,19 @@ 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: makeExtensibleWithInterface + (fixedPoint: extend: fixedPoint // { ${extenderName} = extend; }); + + # Similar to `makeExtensible`, but expects you to implement the + # final interface for the result. Specifically, it takes an extra + # argument: a function that takes the final result and the `extend` + # function as arguments, and returns a transformed result + # (preferably one that contains the `extend` function). This is + # mainly useful for getting to choose what to name the `extend` + # function in the resulting attribute set. But it's also useful for + # having an internal structure that extensions can see, but the user + # facing code cannot. + makeExtensibleWithInterface = interface: fext: interface + (fix' fext) + (f: makeExtensibleWithInterface interface (extends f fext)); }