Add some primops to lib
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Operations on attribute sets.
|
||||
|
||||
with {
|
||||
inherit (builtins) head tail isString;
|
||||
inherit (builtins) head tail;
|
||||
inherit (import ./trivial.nix) or;
|
||||
inherit (import ./default.nix) fold;
|
||||
inherit (import ./strings.nix) concatStringsSep;
|
||||
@@ -100,7 +100,7 @@ rec {
|
||||
(AttrSet -> Bool) -> AttrSet -> AttrSet
|
||||
|
||||
Example:
|
||||
collect builtins.isList { a = { b = ["b"]; }; c = [1]; }
|
||||
collect isList { a = { b = ["b"]; }; c = [1]; }
|
||||
=> [["b"] [1]]
|
||||
|
||||
collect (x: x ? outPath)
|
||||
|
||||
@@ -21,8 +21,6 @@ let
|
||||
in
|
||||
{ inherit trivial lists strings stringsWithDeps attrsets sources options
|
||||
modules types meta debug maintainers licenses platforms systems;
|
||||
# Pull in some builtins not included elsewhere.
|
||||
inherit (builtins) pathExists readFile;
|
||||
}
|
||||
# !!! don't include everything at top-level; perhaps only the most
|
||||
# commonly used functions.
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# General list operations.
|
||||
let
|
||||
|
||||
inherit (import ./trivial.nix) deepSeq;
|
||||
with import ./trivial.nix;
|
||||
|
||||
let
|
||||
|
||||
inc = builtins.add 1;
|
||||
|
||||
dec = n: builtins.sub n 1;
|
||||
|
||||
in rec {
|
||||
inherit (builtins) head tail length isList add sub lessThan elemAt;
|
||||
|
||||
inherit (builtins) head tail length isList elemAt;
|
||||
|
||||
|
||||
# Create a list consisting of a single element. `singleton x' is
|
||||
@@ -55,7 +57,7 @@ in rec {
|
||||
else [ (f (inc n) (elemAt list n)) ] ++ imap' (inc n);
|
||||
in imap' 0;
|
||||
|
||||
|
||||
|
||||
# Concatenate a list of lists.
|
||||
concatLists = builtins.concatLists or (fold (x: y: x ++ y) []);
|
||||
|
||||
@@ -72,7 +74,7 @@ in rec {
|
||||
then fold (x: y: (flatten x) ++ y) [] x
|
||||
else [x];
|
||||
|
||||
|
||||
|
||||
# Filter a list using a predicate; that is, return a list containing
|
||||
# every element from `list' for which `pred' returns true.
|
||||
filter =
|
||||
@@ -80,11 +82,11 @@ in rec {
|
||||
(pred: list:
|
||||
fold (x: y: if pred x then [x] ++ y else y) [] list);
|
||||
|
||||
|
||||
|
||||
# Remove elements equal to 'e' from a list. Useful for buildInputs.
|
||||
remove = e: filter (x: x != e);
|
||||
|
||||
|
||||
|
||||
# Return true if `list' has an element `x'.
|
||||
elem =
|
||||
builtins.elem or
|
||||
@@ -106,7 +108,7 @@ in rec {
|
||||
findFirst = pred: default: list:
|
||||
let found = filter pred list;
|
||||
in if found == [] then default else head found;
|
||||
|
||||
|
||||
|
||||
# Return true iff function `pred' returns true for at least element
|
||||
# of `list'.
|
||||
@@ -136,16 +138,16 @@ in rec {
|
||||
# If argument is a list, return it; else, wrap it in a singleton
|
||||
# list. If you're using this, you should almost certainly
|
||||
# reconsider if there isn't a more "well-typed" approach.
|
||||
toList = x: if builtins.isList x then x else [x];
|
||||
toList = x: if isList x then x else [x];
|
||||
|
||||
|
||||
|
||||
# Return a list of integers from `first' up to and including `last'.
|
||||
range = first: last:
|
||||
if builtins.lessThan last first
|
||||
if lessThan last first
|
||||
then []
|
||||
else [first] ++ range (builtins.add first 1) last;
|
||||
else [first] ++ range (add first 1) last;
|
||||
|
||||
|
||||
|
||||
# Partition the elements of a list in two lists, `right' and
|
||||
# `wrong', depending on the evaluation of a predicate.
|
||||
partition = pred:
|
||||
@@ -160,7 +162,7 @@ in rec {
|
||||
let
|
||||
len1 = length fst;
|
||||
len2 = length snd;
|
||||
len = if builtins.lessThan len1 len2 then len1 else len2;
|
||||
len = if lessThan len1 len2 then len1 else len2;
|
||||
zipListsWith' = n:
|
||||
if n != len then
|
||||
[ (f (elemAt fst n) (elemAt snd n)) ]
|
||||
@@ -207,7 +209,7 @@ in rec {
|
||||
[ (elemAt list n) ] ++ take' (inc n);
|
||||
in take' 0;
|
||||
|
||||
|
||||
|
||||
# Remove the first (at most) N elements of a list.
|
||||
drop = count: list:
|
||||
let
|
||||
@@ -219,7 +221,8 @@ in rec {
|
||||
drop' (dec n) ++ [ (elemAt list n) ];
|
||||
in drop' (dec len);
|
||||
|
||||
|
||||
|
||||
# Return the last element of a list.
|
||||
last = list:
|
||||
assert list != []; elemAt list (dec (length list));
|
||||
|
||||
@@ -237,5 +240,7 @@ in rec {
|
||||
else [];
|
||||
in zipTwoLists' 0;
|
||||
|
||||
|
||||
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ rec {
|
||||
closeModules = modules: args:
|
||||
let
|
||||
toClosureList = file: parentKey: imap (n: x:
|
||||
if isAttrs x || builtins.isFunction x then
|
||||
if isAttrs x || isFunction x then
|
||||
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
|
||||
else
|
||||
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
|
||||
@@ -74,7 +74,7 @@ rec {
|
||||
config = removeAttrs m ["key" "_file" "require" "imports"];
|
||||
};
|
||||
|
||||
applyIfFunction = f: arg: if builtins.isFunction f then f arg else f;
|
||||
applyIfFunction = f: arg: if isFunction f then f arg else f;
|
||||
|
||||
/* Merge a list of modules. This will recurse over the option
|
||||
declarations in all modules, combining them into a single set.
|
||||
@@ -260,7 +260,7 @@ rec {
|
||||
options' = opt.options or
|
||||
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
|
||||
coerce = x:
|
||||
if builtins.isFunction x then x
|
||||
if isFunction x then x
|
||||
else { config, ... }: { options = x; };
|
||||
options = map coerce (flatten options');
|
||||
f = tp:
|
||||
|
||||
@@ -34,12 +34,12 @@ rec {
|
||||
mergeDefaultOption = loc: defs:
|
||||
let list = getValues defs; in
|
||||
if length list == 1 then head list
|
||||
else if all builtins.isFunction list then x: mergeDefaultOption loc (map (f: f x) 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 builtins.isBool list then fold lib.or false list
|
||||
else if all builtins.isString list then lib.concatStrings list
|
||||
else if all builtins.isInt list && all (x: x == head list) list then head list
|
||||
else if all isBool list then fold 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)}.";
|
||||
|
||||
/* Obsolete, will remove soon. Specify an option type or apply
|
||||
@@ -54,7 +54,7 @@ rec {
|
||||
|
||||
mergeListOption = mergeTypedOption "list" isList concatLists;
|
||||
|
||||
mergeStringOption = mergeTypedOption "string" builtins.isString lib.concatStrings;
|
||||
mergeStringOption = mergeTypedOption "string" isString lib.concatStrings;
|
||||
|
||||
mergeOneOption = loc: defs:
|
||||
if defs == [] then abort "This case should never happen."
|
||||
|
||||
@@ -7,7 +7,8 @@ inherit (builtins) add sub lessThan length;
|
||||
in
|
||||
|
||||
rec {
|
||||
inherit (builtins) stringLength substring head tail;
|
||||
|
||||
inherit (builtins) stringLength substring head tail isString;
|
||||
|
||||
|
||||
# Concatenate a list of strings.
|
||||
|
||||
@@ -16,7 +16,7 @@ rec {
|
||||
or = x: y: x || y;
|
||||
and = x: y: x && y;
|
||||
mergeAttrs = x: y: x // y;
|
||||
|
||||
|
||||
# Take a function and evaluate it with its own returned value.
|
||||
fix = f: let result = f result; in result;
|
||||
|
||||
@@ -26,7 +26,7 @@ rec {
|
||||
# `seq x y' evaluates x, then returns y. That is, it forces strict
|
||||
# evaluation of its first argument.
|
||||
seq = x: y: if x == null then y else y;
|
||||
|
||||
|
||||
# Like `seq', but recurses into lists and attribute sets to force evaluation
|
||||
# of all list elements/attributes.
|
||||
deepSeq = x: y:
|
||||
@@ -35,4 +35,10 @@ rec {
|
||||
else if builtins.isAttrs x
|
||||
then deepSeqAttrs x y
|
||||
else seq x y;
|
||||
|
||||
# Pull in some builtins not included elsewhere.
|
||||
inherit (builtins)
|
||||
pathExists readFile isBool isFunction
|
||||
isInt add sub lessThan;
|
||||
|
||||
}
|
||||
|
||||
@@ -48,19 +48,19 @@ rec {
|
||||
|
||||
bool = mkOptionType {
|
||||
name = "boolean";
|
||||
check = builtins.isBool;
|
||||
check = isBool;
|
||||
merge = loc: fold (x: y: x.value || y) false;
|
||||
};
|
||||
|
||||
int = mkOptionType {
|
||||
name = "integer";
|
||||
check = builtins.isInt;
|
||||
check = isInt;
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
|
||||
str = mkOptionType {
|
||||
name = "string";
|
||||
check = builtins.isString;
|
||||
check = isString;
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ rec {
|
||||
# separator between the values).
|
||||
separatedString = sep: mkOptionType {
|
||||
name = "string";
|
||||
check = builtins.isString;
|
||||
check = isString;
|
||||
merge = loc: defs: concatStringsSep sep (getValues defs);
|
||||
};
|
||||
|
||||
@@ -170,7 +170,7 @@ rec {
|
||||
|
||||
functionTo = elemType: mkOptionType {
|
||||
name = "function that evaluates to a(n) ${elemType.name}";
|
||||
check = builtins.isFunction;
|
||||
check = isFunction;
|
||||
merge = loc: defs:
|
||||
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
|
||||
getSubOptions = elemType.getSubOptions;
|
||||
@@ -183,10 +183,10 @@ rec {
|
||||
in
|
||||
mkOptionType rec {
|
||||
name = "submodule";
|
||||
check = x: isAttrs x || builtins.isFunction x;
|
||||
check = x: isAttrs x || isFunction x;
|
||||
merge = loc: defs:
|
||||
let
|
||||
coerce = def: if builtins.isFunction def then def else { config = def; };
|
||||
coerce = def: if isFunction def then def else { config = def; };
|
||||
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
|
||||
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
|
||||
getSubOptions = prefix: (evalModules
|
||||
|
||||
Reference in New Issue
Block a user