summary refs log tree commit diff
path: root/pkgs/lib/attrsets.nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2009-03-10 15:18:38 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2009-03-10 15:18:38 +0000
commitb53ef575548dc53dd39bbe75e2a00b26d943f161 (patch)
treeb07976e2f5ecf69cece9efb3afd9c69ca908c07d /pkgs/lib/attrsets.nix
parente629ce0e0787fb12cd7e087c8760ea84021ec47b (diff)
downloadnixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar.gz
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar.bz2
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar.lz
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar.xz
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.tar.zst
nixpkgs-b53ef575548dc53dd39bbe75e2a00b26d943f161.zip
* Moved mapAttrs to attrsets.nix.
* Added a function mapAttrsRecursive, which is like mapAttrs, but
  recursively applies itself to attribute sets.
* Commented and cleaned up some functions.

svn path=/nixpkgs/trunk/; revision=14495
Diffstat (limited to 'pkgs/lib/attrsets.nix')
-rw-r--r--pkgs/lib/attrsets.nix90
1 files changed, 79 insertions, 11 deletions
diff --git a/pkgs/lib/attrsets.nix b/pkgs/lib/attrsets.nix
index a394ff5bd18..dba58f00789 100644
--- a/pkgs/lib/attrsets.nix
+++ b/pkgs/lib/attrsets.nix
@@ -3,16 +3,18 @@
 with {
   inherit (builtins) head tail;
   inherit (import ./default.nix) fold;
+  inherit (import ./strings.nix) concatStringsSep;
 };
 
 rec {
   inherit (builtins) attrNames listToAttrs hasAttr isAttrs;
 
 
-  # Return an attribute from nested attribute sets.  For instance ["x"
-  # "y"] applied to some set e returns e.x.y, if it exists.  The
-  # default value is returned otherwise.  !!! there is also
-  # builtins.getAttr (is there a better name for this function?)
+  /* Return an attribute from nested attribute sets.  For instance
+     ["x" "y"] applied to some set e returns e.x.y, if it exists.  The
+     default value is returned otherwise.  !!! there is also
+     builtins.getAttr (is there a better name for this function?)
+  */
   getAttr = attrPath: default: e:
     let attr = head attrPath;
     in
@@ -21,14 +23,80 @@ rec {
       then getAttr (tail attrPath) default (builtins.getAttr attr e)
       else default;
 
-  # ordered by name
-  attrValues = attrs: attrVals (__attrNames attrs) attrs;
 
-  attrVals = nameList : attrSet :
-    map (x: builtins.getAttr x attrSet) nameList;
+  getAttrFromPath = attrPath: set:
+    let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
+    in getAttr attrPath (abort errorMsg) set;
+      
 
-  # iterates over a list of attributes collecting the attribute attr if it exists
-  catAttrs = attr : l : fold ( s : l : if (hasAttr attr s) then [(builtins.getAttr attr s)] ++ l else l) [] l;
+  /* Return the specified attributes from a set.
 
+     Example:
+       attrVals ["a" "b" "c"] as
+       => [as.a as.b as.c]
+  */
+  attrVals = nameList: set:
+    map (x: builtins.getAttr x set) nameList;
 
-}
\ No newline at end of file
+
+  /* Return the values of all attributes in the given set, sorted by
+     attribute name.
+
+     Example:
+       attrValues {c = 3; a = 1; b = 2;}
+       => [1 2 3]
+  */
+  attrValues = attrs: attrVals (attrNames attrs) attrs;
+
+
+  /* Collect each attribute named `attr' from a list of attribute
+     sets.  Sets that don't contain the named attribute are ignored.
+
+     Example:
+       catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
+       => [1 2]
+  */
+  catAttrs = attr: l: fold (s: l: if hasAttr attr s then [(builtins.getAttr attr s)] ++ l else l) [] l;
+
+
+  /* Utility function that creates a {name, value} pair as expected by
+     builtins.listToAttrs. */
+  nameValuePair = name: value: { inherit name value; };
+
+  
+  /* Apply a function to each element in an attribute set.  The
+     function takes two arguments --- the attribute name and its value
+     --- and returns the new value for the attribute.  The result is a
+     new attribute set.
+
+     Example:
+       mapAttrs (name: value: name + "-" + value)
+          {x = "foo"; y = "bar";}
+       => {x = "x-foo"; y = "y-bar";}
+  */
+  mapAttrs = f: set:
+    listToAttrs (map (attr: nameValuePair attr (f attr (builtins.getAttr attr set))) (attrNames set));
+    
+
+  /* Like `mapAttrs', except that it recursively applies itself to
+     values that attribute sets.  Also, the first argument is a *list*
+     of the names of the containing attributes.
+
+     Example:
+       mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
+         { n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
+       => { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
+  */
+  mapAttrsRecursive =
+    let
+      recurse = path: f: set:
+        let
+          g =
+            name: value:
+            if isAttrs value
+              then recurse (path ++ [name]) f value
+              else f (path ++ [name]) value;
+        in mapAttrs g set;
+    in recurse [];
+  
+}