Last active
August 7, 2017 19:50
-
-
Save bennofs/f9cffeb8f8320cd7a770d51e4a69e658 to your computer and use it in GitHub Desktop.
Nix self/super override challenges. Solutions: https://gist.github.com/bennofs/65af82328bbd0c0e5db19d2a99070cc7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let | |
# Imports | |
nixpkgs = import <nixpkgs> {}; | |
inherit (nixpkgs) lib; | |
inherit (lib) mapAttrs fix extends; | |
# Helpers | |
makeExtendable = base: | |
fix base // { | |
extend = f: makeExtendable (extends f base); | |
}; | |
makeCalculated = description: expr: value: | |
"value of `${expr}` as observed by ${description} is: \n${value}"; | |
# This is our base, it takes the role of `pkgs` in the following examples. | |
# `.extend` works the same as `.overridePackages` does for `pkgs`. | |
# | |
# The attributes of base are plain values instead of packages, since this is | |
# easier for illustration and you can better see what happens. | |
# | |
# `attr` represents a package without dependencies, while `calculated-attr` is | |
# like a package that depends on `attr`. | |
base = makeExtendable (self: { | |
attr = "base attribute"; | |
calculated-attr = makeCalculated "base" "self.attr" self.attr; | |
_result = self.calculated-attr; | |
}); | |
# Can you guess the value of the `._result` attribute for each of these sets without | |
# using a nix evaluator? | |
# (These are sorted alphabetically) | |
overridden = rec { | |
attr-base = base.extend (self: super: { | |
attr = makeCalculated "child" "base.attr" base.attr; | |
}); | |
attr-base-calculated = base.extend (self: super: { | |
attr = "child attribute"; | |
_result = makeCalculated "attr-base-calculated" "base.calculated-attr" base.calculated-attr; | |
}); | |
attr-base-calculated-constant = attr-base-calculated.extend (self: super: { | |
calculated-attr = "grandchild calculated attribute"; | |
}); | |
attr-constant = base.extend (self: super: { | |
attr = "constant attribute value"; | |
}); | |
attr-self = base.extend (self: super: { | |
attr = makeCalculated "child" "self.attr" self.attr; | |
_result = "infinite recursion"; | |
}); | |
attr-self-calculated = base.extend (self: super: { | |
attr = "child attribute"; | |
_result = makeCalculated "child" "self.calculated-attr" self.calculated-attr; | |
}); | |
attr-self-calculated-constant = attr-self-calculated.extend (self: super: { | |
calculated-attr = "grandchild calculated attribute"; | |
}); | |
attr-self-constant = attr-self.extend (self: super: { | |
attr = "grandchild attribute"; | |
_result = self.calculated-attr; | |
}); | |
attr-super = base.extend (self: super: { | |
attr = makeCalculated "child" "super.attr" super.attr; | |
}); | |
attr-super-calculated = base.extend (self: super: { | |
attr = "child attribute"; | |
_result = makeCalculated "child" "super.calculated-attr" super.calculated-attr; | |
}); | |
attr-super-calculated-constant = attr-super-calculated.extend (self: super: { | |
calculated-attr = "grandchild calculated attribute"; | |
}); | |
attr-union = base // { attr = "attr-union attribute"; }; | |
}; | |
# For each record, we get the value of the `value` attribute. | |
results = mapAttrs (key: s: s._result) overridden; | |
in results |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment