Add foldl' primop
This commit is contained in:
parent
887bb5fa5a
commit
61af14a921
3 changed files with 38 additions and 1 deletions
|
@ -313,6 +313,19 @@ stdenv.mkDerivation {
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
|
<varlistentry><term><function>builtins.foldl’</function>
|
||||||
|
<replaceable>op</replaceable> <replaceable>nul</replaceable> <replaceable>list</replaceable></term>
|
||||||
|
|
||||||
|
<listitem><para>Reduce a list by applying a binary operator, from
|
||||||
|
left to right, e.g. <literal>foldl’ op nul [x0 x1 x2 ...] = op (op
|
||||||
|
(op nul x0) x1) x2) ...</literal>. The operator is applied
|
||||||
|
strictly, i.e., its arguments are evaluated first. For example,
|
||||||
|
<literal>foldl’ (x: y: x + y) 0 [1 2 3]</literal> evaluates to
|
||||||
|
6.</para></listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry><term><function>builtins.fromJSON</function> <replaceable>e</replaceable></term>
|
<varlistentry><term><function>builtins.fromJSON</function> <replaceable>e</replaceable></term>
|
||||||
|
|
||||||
<listitem><para>Convert a JSON string to a Nix
|
<listitem><para>Convert a JSON string to a Nix
|
||||||
|
|
|
@ -1304,6 +1304,29 @@ static void prim_length(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reduce a list by applying a binary operator, from left to
|
||||||
|
right. The operator is applied strictly. */
|
||||||
|
static void prim_foldlStrict(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
|
{
|
||||||
|
state.forceFunction(*args[0], pos);
|
||||||
|
state.forceList(*args[2], pos);
|
||||||
|
|
||||||
|
Value * vCur = args[1];
|
||||||
|
|
||||||
|
if (args[2]->list.length)
|
||||||
|
for (unsigned int n = 0; n < args[2]->list.length; ++n) {
|
||||||
|
Value vTmp;
|
||||||
|
state.callFunction(*args[0], *vCur, vTmp, pos);
|
||||||
|
vCur = n == args[2]->list.length - 1 ? &v : state.allocValue();
|
||||||
|
state.callFunction(vTmp, *args[2]->list.elems[n], *vCur, pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
v = *vCur;
|
||||||
|
|
||||||
|
state.forceValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Integer arithmetic
|
* Integer arithmetic
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
@ -1641,6 +1664,7 @@ void EvalState::createBaseEnv()
|
||||||
addPrimOp("__elem", 2, prim_elem);
|
addPrimOp("__elem", 2, prim_elem);
|
||||||
addPrimOp("__concatLists", 1, prim_concatLists);
|
addPrimOp("__concatLists", 1, prim_concatLists);
|
||||||
addPrimOp("__length", 1, prim_length);
|
addPrimOp("__length", 1, prim_length);
|
||||||
|
addPrimOp("__foldl'", 3, prim_foldlStrict);
|
||||||
|
|
||||||
// Integer arithmetic
|
// Integer arithmetic
|
||||||
addPrimOp("__add", 2, prim_add);
|
addPrimOp("__add", 2, prim_add);
|
||||||
|
|
|
@ -17,7 +17,7 @@ rec {
|
||||||
then fold (x: y: (flatten x) ++ y) [] x
|
then fold (x: y: (flatten x) ++ y) [] x
|
||||||
else [x];
|
else [x];
|
||||||
|
|
||||||
sum = fold (x: y: add x y) 0;
|
sum = foldl' (x: y: add x y) 0;
|
||||||
|
|
||||||
hasSuffix = ext: fileName:
|
hasSuffix = ext: fileName:
|
||||||
let lenFileName = stringLength fileName;
|
let lenFileName = stringLength fileName;
|
||||||
|
|
Loading…
Reference in a new issue