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