From 637e35deb99c5efbb8bd760a3ad08d3899534ead Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Jul 2015 17:19:21 +0200 Subject: [PATCH] Use foldl' instead of fold in some places --- lib/lists.nix | 8 ++++++-- lib/modules.nix | 14 +++++++------- lib/options.nix | 6 +++--- lib/strings.nix | 2 +- lib/types.nix | 2 +- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/lists.nix b/lib/lists.nix index fa8cbddfd943..9cb164aaade4 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -38,6 +38,10 @@ rec { in foldl' (length list - 1); + # Strict version of foldl. + foldl' = builtins.foldl' or foldl; + + # map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] == # ["a-1" "b-2"]' imap = f: list: @@ -59,7 +63,7 @@ rec { # == [1 2 3 4 5]' and `flatten 1 == [1]'. flatten = x: if isList x - then fold (x: y: (flatten x) ++ y) [] x + then foldl' (x: y: x ++ (flatten y)) [] x else [x]; @@ -96,7 +100,7 @@ rec { # Count how many times function `pred' returns true for the elements # of `list'. - count = pred: fold (x: c: if pred x then c + 1 else c) 0; + count = pred: foldl' (c: x: if pred x then c + 1 else c) 0; # Return a singleton list or an empty list, depending on a boolean diff --git a/lib/modules.nix b/lib/modules.nix index ea600127617b..22e8b200f761 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -76,8 +76,8 @@ rec { else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"]; in if options._module.check.value && set ? _definedNames then - fold (m: res: - fold (name: res: + foldl' (res: m: + foldl' (res: name: if set ? ${name} then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.") res m.names) res set._definedNames @@ -225,7 +225,7 @@ rec { 'opts' is a list of modules. Each module has an options attribute which correspond to the definition of 'loc' in 'opt.file'. */ mergeOptionDecls = loc: opts: - fold (opt: res: + foldl' (res: opt: if opt.options ? default && res ? default || opt.options ? example && res ? example || opt.options ? description && res ? description || @@ -251,7 +251,7 @@ rec { else if opt.options ? options then map (coerceOption opt.file) options' ++ res.options else res.options; in opt.options // res // - { declarations = [opt.file] ++ res.declarations; + { declarations = res.declarations ++ [opt.file]; options = submodules; } ) { inherit loc; declarations = []; options = []; } opts; @@ -302,8 +302,8 @@ rec { in processOrder (processOverride (processIfAndMerge defs)); - # Type-check the remaining definitions, and merge them - mergedValue = fold (def: res: + # Type-check the remaining definitions, and merge them. + mergedValue = foldl' (res: def: if type.check def.value then res else throw "The option value `${showOption loc}' in `${def.file}' is not a ${type.name}.") (type.merge loc defsFinal) defsFinal; @@ -384,7 +384,7 @@ rec { defaultPrio = 100; getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio; min = x: y: if x < y then x else y; - highestPrio = fold (def: prio: min (getPrio def) prio) 9999 defs; + highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs; strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def; in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs; diff --git a/lib/options.nix b/lib/options.nix index bb72ad6d125c..6e8e9ce00061 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -53,8 +53,8 @@ rec { if length list == 1 then head list else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list) else if all isList list then concatLists list - else if all isAttrs list then fold lib.mergeAttrs {} list - else if all isBool list then fold lib.or false list + else if all isAttrs list then foldl' lib.mergeAttrs {} list + else if all isBool list then foldl' lib.or false list else if all isString list then lib.concatStrings list else if all isInt list && all (x: x == head list) list then head list else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}."; @@ -68,7 +68,7 @@ rec { /* "Merge" option definitions by checking that they all have the same value. */ mergeEqualOption = loc: defs: if defs == [] then abort "This case should never happen." - else fold (def: val: + else foldl' (val: def: if def.value != val then throw "The option `${showOption loc}' has conflicting definitions, in ${showFiles (getFiles defs)}." else diff --git a/lib/strings.nix b/lib/strings.nix index d9f7f6c2db81..f0ecb15ab2d3 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -12,7 +12,7 @@ rec { # Concatenate a list of strings. - concatStrings = lib.fold (x: y: x + y) ""; + concatStrings = lib.foldl' (x: y: x + y) ""; # Map a function over a list and concatenate the resulting strings. diff --git a/lib/types.nix b/lib/types.nix index 0a54a5598f14..49f24b022de9 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -88,7 +88,7 @@ rec { attrs = mkOptionType { name = "attribute set"; check = isAttrs; - merge = loc: fold (def: mergeAttrs def.value) {}; + merge = loc: foldl' (res: def: mergeAttrs res def.value) {}; }; # derivation is a reserved keyword.