1{ lib }:
2rec {
3
4 /* The identity function
5 For when you need a function that does “nothing”.
6
7 Type: id :: a -> a
8 */
9 id = x: x;
10
11 /* The constant function
12 Ignores the second argument.
13 Or: Construct a function that always returns a static value.
14
15 Type: const :: a -> b -> a
16 Example:
17 let f = const 5; in f 10
18 => 5
19 */
20 const = x: y: x;
21
22
23 ## Named versions corresponding to some builtin operators.
24
25 /* Concat two strings */
26 concat = x: y: x ++ y;
27
28 /* boolean “or” */
29 or = x: y: x || y;
30
31 /* boolean “and” */
32 and = x: y: x && y;
33
34 /* Convert a boolean to a string.
35 Note that toString on a bool returns "1" and "".
36 */
37 boolToString = b: if b then "true" else "false";
38
39 /* Merge two attribute sets shallowly, right side trumps left
40
41 Example:
42 mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; }
43 => { a = 1; b = 3; c = 4; }
44 */
45 mergeAttrs = x: y: x // y;
46
47 # Flip the order of the arguments of a binary function.
48 flip = f: a: b: f b a;
49
50 # Apply function if argument is non-null
51 mapNullable = f: a: if isNull a then a else f a;
52
53 # Pull in some builtins not included elsewhere.
54 inherit (builtins)
55 pathExists readFile isBool
56 isInt add sub lessThan
57 seq deepSeq genericClosure;
58
59 inherit (lib.strings) fileContents;
60
61 # Return the Nixpkgs version number.
62 nixpkgsVersion =
63 let suffixFile = ../.version-suffix; in
64 fileContents ../.version
65 + (if pathExists suffixFile then fileContents suffixFile else "pre-git");
66
67 # Whether we're being called by nix-shell.
68 inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
69
70 # Return minimum/maximum of two numbers.
71 min = x: y: if x < y then x else y;
72 max = x: y: if x > y then x else y;
73
74 /* Integer modulus
75
76 Example:
77 mod 11 10
78 => 1
79 mod 1 10
80 => 1
81 */
82 mod = base: int: base - (int * (builtins.div base int));
83
84 /* C-style comparisons
85
86 a < b, compare a b => -1
87 a == b, compare a b => 0
88 a > b, compare a b => 1
89 */
90 compare = a: b:
91 if a < b
92 then -1
93 else if a > b
94 then 1
95 else 0;
96
97 /* Split type into two subtypes by predicate `p`, take all elements
98 of the first subtype to be less than all the elements of the
99 second subtype, compare elements of a single subtype with `yes`
100 and `no` respectively.
101
102 Example:
103
104 let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
105
106 cmp "a" "z" => -1
107 cmp "fooa" "fooz" => -1
108
109 cmp "f" "a" => 1
110 cmp "fooa" "a" => -1
111 # while
112 compare "fooa" "a" => 1
113
114 */
115 splitByAndCompare = p: yes: no: a: b:
116 if p a
117 then if p b then yes a b else -1
118 else if p b then 1 else no a b;
119
120 /* Reads a JSON file. */
121 importJSON = path:
122 builtins.fromJSON (builtins.readFile path);
123
124 /* See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
125 to expand to Nix builtins that carry metadata so that Nix can filter out
126 the INFO messages without parsing the message string.
127
128 Usage:
129 {
130 foo = lib.warn "foo is deprecated" oldFoo;
131 }
132
133 TODO: figure out a clever way to integrate location information from
134 something like __unsafeGetAttrPos.
135 */
136 warn = msg: builtins.trace "WARNING: ${msg}";
137 info = msg: builtins.trace "INFO: ${msg}";
138
139 # | Add metadata about expected function arguments to a function.
140 # The metadata should match the format given by
141 # builtins.functionArgs, i.e. a set from expected argument to a bool
142 # representing whether that argument has a default or not.
143 # setFunctionArgs : (a → b) → Map String Bool → (a → b)
144 #
145 # This function is necessary because you can't dynamically create a
146 # function of the { a, b ? foo, ... }: format, but some facilities
147 # like callPackage expect to be able to query expected arguments.
148 setFunctionArgs = f: args:
149 { # TODO: Should we add call-time "type" checking like built in?
150 __functor = self: f;
151 __functionArgs = args;
152 };
153
154 # | Extract the expected function arguments from a function.
155 # This works both with nix-native { a, b ? foo, ... }: style
156 # functions and functions with args set with 'setFunctionArgs'. It
157 # has the same return type and semantics as builtins.functionArgs.
158 # setFunctionArgs : (a → b) → Map String Bool.
159 functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
160
161 isFunction = f: builtins.isFunction f ||
162 (f ? __functor && isFunction (f.__functor f));
163}