lib/lists: rename fold to foldr & improve fold docs
In order to better distinguish foldr from foldl the default name is changed to foldr, but fold is still a synonym. Additionally the docs are improved and examples added.
This commit is contained in:
parent
b052a36294
commit
cb9ff8bfa7
@ -16,17 +16,22 @@ rec {
|
||||
*/
|
||||
singleton = x: [x];
|
||||
|
||||
/* "Fold" a binary function `op' between successive elements of
|
||||
`list' with `nul' as the starting value, i.e., `fold op nul [x_1
|
||||
x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is
|
||||
Haskell's foldr).
|
||||
/* “right fold” a binary function `op' between successive elements of
|
||||
`list' with `nul' as the starting value, i.e.,
|
||||
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'.
|
||||
Type:
|
||||
foldr :: (a -> b -> b) -> b -> [a] -> b
|
||||
|
||||
Example:
|
||||
concat = fold (a: b: a + b) "z"
|
||||
concat = foldr (a: b: a + b) "z"
|
||||
concat [ "a" "b" "c" ]
|
||||
=> "abcz"
|
||||
# different types
|
||||
strange = foldr (int: str: toString (int + 1) + str) "a"
|
||||
strange [ 1 2 3 4 ]
|
||||
=> "2345a"
|
||||
*/
|
||||
fold = op: nul: list:
|
||||
foldr = op: nul: list:
|
||||
let
|
||||
len = length list;
|
||||
fold' = n:
|
||||
@ -35,13 +40,25 @@ rec {
|
||||
else op (elemAt list n) (fold' (n + 1));
|
||||
in fold' 0;
|
||||
|
||||
/* Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
|
||||
x_1) x_2) ... x_n)'.
|
||||
/* `fold' is an alias of `foldr' for historic reasons */
|
||||
# FIXME(Profpatsch): deprecate?
|
||||
fold = foldr;
|
||||
|
||||
|
||||
/* “left fold”, like `foldr', but from the left:
|
||||
`foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
|
||||
|
||||
Type:
|
||||
foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
|
||||
Example:
|
||||
lconcat = foldl (a: b: a + b) "z"
|
||||
lconcat [ "a" "b" "c" ]
|
||||
=> "zabc"
|
||||
# different types
|
||||
lstrange = foldl (str: int: str + toString (int + 1)) ""
|
||||
strange [ 1 2 3 4 ]
|
||||
=> "a2345"
|
||||
*/
|
||||
foldl = op: nul: list:
|
||||
let
|
||||
@ -52,7 +69,7 @@ rec {
|
||||
else op (foldl' (n - 1)) (elemAt list n);
|
||||
in foldl' (length list - 1);
|
||||
|
||||
/* Strict version of foldl.
|
||||
/* Strict version of `foldl'.
|
||||
|
||||
The difference is that evaluation is forced upon access. Usually used
|
||||
with small whole results (in contract with lazily-generated list or large
|
||||
@ -140,7 +157,7 @@ rec {
|
||||
any isString [ 1 { } ]
|
||||
=> false
|
||||
*/
|
||||
any = builtins.any or (pred: fold (x: y: if pred x then true else y) false);
|
||||
any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false);
|
||||
|
||||
/* Return true iff function `pred' returns true for all elements of
|
||||
`list'.
|
||||
@ -151,7 +168,7 @@ rec {
|
||||
all (x: x < 3) [ 1 2 3 ]
|
||||
=> false
|
||||
*/
|
||||
all = builtins.all or (pred: fold (x: y: if pred x then y else false) true);
|
||||
all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true);
|
||||
|
||||
/* Count how many times function `pred' returns true for the elements
|
||||
of `list'.
|
||||
@ -219,7 +236,7 @@ rec {
|
||||
=> { right = [ 5 3 4 ]; wrong = [ 1 2 ]; }
|
||||
*/
|
||||
partition = builtins.partition or (pred:
|
||||
fold (h: t:
|
||||
foldr (h: t:
|
||||
if pred h
|
||||
then { right = [h] ++ t.right; wrong = t.wrong; }
|
||||
else { right = t.right; wrong = [h] ++ t.wrong; }
|
||||
|
Loading…
Reference in New Issue
Block a user