1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 12:20:26 +02:00
(SRFI-1 Fold and Map): Rewrite fold, pair-fold and reduce for clarity.
This commit is contained in:
Kevin Ryde 2005-02-28 00:33:40 +00:00
parent ad3d5a65c8
commit 5f708db610

View file

@ -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]