lib.lists.foldl': Redo documentation

Co-Authored-By: Robert Hensing <robert@roberthensing.nl>
This commit is contained in:
Silvan Mosberger 2023-09-22 02:42:29 +02:00
parent 9893fee947
commit 857a844ea8

View file

@ -86,15 +86,56 @@ rec {
else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1);
/* Strict version of `foldl`.
/*
Reduce a list by applying a binary operator from left to right,
starting with an initial accumulator.
The difference is that evaluation is forced upon access. Usually used
with small whole results (in contrast with lazily-generated list or large
lists where only a part is consumed.)
After each application of the operator, the resulting value is evaluated.
This behavior makes this function stricter than [`foldl`](#function-library-lib.lists.foldl).
Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
A call like
```nix
foldl' op acc [ x x x ... x x ]
```
is (denotationally) equivalent to the following,
but with the added benefit that `foldl'` itself will never overflow the stack.
```nix
let
acc = op acc x ;
acc = builtins.seq acc (op acc x );
acc = builtins.seq acc (op acc x );
...
acc = builtins.seq acc (op acc x);
acc = builtins.seq acc (op acc x );
in
acc
# Or ignoring builtins.seq
op (op (... (op (op (op acc x) x) x) ...) x) x
```
Type: foldl' :: (acc -> x -> acc) -> acc -> [x] -> acc
Example:
foldl' (acc: x: acc + x) 0 [1 2 3]
=> 6
*/
foldl' = builtins.foldl';
foldl' =
/* The binary operation to run, where the two arguments are:
1. `acc`: The current accumulator value: Either the initial one for the first iteration, or the result of the previous iteration
2. `x`: The corresponding list element for this iteration
*/
op:
# The initial accumulator value
acc:
# The list to fold
list:
builtins.foldl' op acc list;
/* Map with index starting from 0