mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
More of:
(SRFI-1 Fold and Map): Rewrite fold, pair-fold and reduce for clarity.
This commit is contained in:
parent
ad3d5a65c8
commit
5f708db610
1 changed files with 33 additions and 54 deletions
|
@ -522,9 +522,9 @@ elements from a list,
|
|||
@end example
|
||||
|
||||
Clearly the same sort of thing can be done with a @code{for-each} and
|
||||
a variable in which build the result, but a self-contained @var{proc}
|
||||
can be re-used in multiple contexts, where a @code{for-each} would
|
||||
have to be written out each time.
|
||||
a variable in which to build the result, but a self-contained
|
||||
@var{proc} can be re-used in multiple contexts, where a
|
||||
@code{for-each} would have to be written out each time.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} pair-fold proc init lst1 @dots{} lstN
|
||||
|
@ -533,68 +533,47 @@ The same as @code{fold} and @code{fold-right}, but apply @var{proc} to
|
|||
the pairs of the lists instead of the list elements.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} reduce proc identity lst
|
||||
@deffnx {Scheme Procedure} reduce-right proc identity lst
|
||||
@code{reduce} is a variant of @code{fold} (see above), designed for
|
||||
cases where the initial value is an ``identity'', so that @var{proc}
|
||||
can start directly from the first element of @var{lst}.
|
||||
@deffn {Scheme Procedure} reduce proc default lst
|
||||
@deffnx {Scheme Procedure} reduce-right proc default lst
|
||||
@code{reduce} is a variant of @code{fold}, where the first call to
|
||||
@var{proc} is on two elements from @var{lst}, rather than one element
|
||||
and a given initial value.
|
||||
|
||||
Consider folding with @code{+} and initial value 0, calls would be for
|
||||
instance
|
||||
If @var{lst} is empty, @code{reduce} returns @var{default} (this is
|
||||
the only use for @var{default}). If @var{lst} has just one element
|
||||
then that's the return value. Otherwise @var{proc} is called on the
|
||||
elements of @var{lst}.
|
||||
|
||||
Each @var{proc} call is @code{(@var{proc} @var{elem} @var{previous})},
|
||||
where @var{elem} is from @var{lst} (the second and subsequent elements
|
||||
of @var{lst}), and @var{previous} is the return from the previous call
|
||||
to @var{proc}. The first element of @var{lst} is the @var{previous}
|
||||
for the first call to @var{proc}.
|
||||
|
||||
For example, the following adds a list of numbers, the calls made to
|
||||
@code{+} are shown. (Of course @code{+} accepts multiple arguments
|
||||
and can add a list directly, with @code{apply}.)
|
||||
|
||||
@example
|
||||
(fold + 0 '(4 5 6))
|
||||
@result{}
|
||||
(+ 4 0)
|
||||
(+ 5 4)
|
||||
(+ 6 9)
|
||||
(reduce + 0 '(5 6 7)) @result{} 18
|
||||
|
||||
(+ 6 5) @result{} 11
|
||||
(+ 7 11) @result{} 18
|
||||
@end example
|
||||
|
||||
The first call @code{(+ 4 0)} is unnecessary, adding 0 to 4 doesn't
|
||||
change that value. The first element @code{4} may as well be the
|
||||
initial ``previous'' value argument to @var{proc}. This is what
|
||||
@code{reduce} does.
|
||||
|
||||
@example
|
||||
(reduce + 0 '(4 5 6))
|
||||
@result{}
|
||||
(+ 5 4)
|
||||
(+ 6 9)
|
||||
@end example
|
||||
|
||||
The @var{identity} parameter is the return when @var{lst} is empty,
|
||||
that's the only time @var{identity} is used. If @var{lst} has just
|
||||
one element, that's the return with no calls to @var{proc}.
|
||||
@code{reduce} can be used instead of @code{fold} where the @var{init}
|
||||
value is an ``identity'', meaning a value which under @var{proc}
|
||||
doesn't change the result, in this case 0 is an identity since
|
||||
@code{(+ 5 0)} is just 5. @code{reduce} avoids that unnecessary call.
|
||||
|
||||
@code{reduce-right} is a similar variation on @code{fold-right},
|
||||
working from the end (ie.@: the right) of @var{lst}. Calls in this
|
||||
case become
|
||||
|
||||
@example
|
||||
(reduce-right + 0 '(4 5 6))
|
||||
@result{}
|
||||
(+ 5 6)
|
||||
(+ 4 11)
|
||||
@end example
|
||||
working from the end (ie.@: the right) of @var{lst}. The last element
|
||||
of @var{lst} is the @var{previous} for the first call to @var{proc},
|
||||
and the @var{elem} values go from the second last.
|
||||
|
||||
@code{reduce} should be preferred over @code{reduce-right} if the
|
||||
order of processing doesn't matter, or can be arranged either way,
|
||||
since @code{reduce} is a little more efficient.
|
||||
|
||||
In the above examples of course @code{+} takes any number of
|
||||
arguments, so it can be used on a list just with @code{apply}. An
|
||||
example where that's not the case would be SRFI-19 @code{add-duration}
|
||||
(@pxref{SRFI-19 Time}) on a list of durations,
|
||||
|
||||
@example
|
||||
(use-modules (srfi srfi-19))
|
||||
(reduce add-duration
|
||||
(make-time time-duration 0 0)
|
||||
(list (make-time time-duration 0 4)
|
||||
(make-time time-duration 0 5)
|
||||
(make-time time-duration 0 6)))
|
||||
@result{} #<time duration 15 seconds>
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} unfold p f g seed [tail-gen]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue