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><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>
|
||||
|
||||
<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
|
||||
*************************************************************/
|
||||
|
@ -1641,6 +1664,7 @@ void EvalState::createBaseEnv()
|
|||
addPrimOp("__elem", 2, prim_elem);
|
||||
addPrimOp("__concatLists", 1, prim_concatLists);
|
||||
addPrimOp("__length", 1, prim_length);
|
||||
addPrimOp("__foldl'", 3, prim_foldlStrict);
|
||||
|
||||
// Integer arithmetic
|
||||
addPrimOp("__add", 2, prim_add);
|
||||
|
|
|
@ -17,7 +17,7 @@ rec {
|
|||
then fold (x: y: (flatten x) ++ y) [] x
|
||||
else [x];
|
||||
|
||||
sum = fold (x: y: add x y) 0;
|
||||
sum = foldl' (x: y: add x y) 0;
|
||||
|
||||
hasSuffix = ext: fileName:
|
||||
let lenFileName = stringLength fileName;
|
||||
|
|
Loading…
Reference in a new issue