File 2372-Add-a-fold-function-to-the-queue-module.patch of Package erlang
From 025789ff2e81348ff3891cf836180e6981688c08 Mon Sep 17 00:00:00 2001
From: Maria-12648430 <maria-12648430@gmx.net>
Date: Mon, 26 Oct 2020 09:37:52 +0100
Subject: [PATCH 2/3] Add a fold function to the queue module
A fold function in the queue module removes the need for
a conversion to a list in order to achieve the same.
---
lib/stdlib/doc/src/queue.xml | 22 ++++++++++++++++++++++
lib/stdlib/src/queue.erl | 17 ++++++++++++++++-
lib/stdlib/test/queue_SUITE.erl | 7 +++++++
3 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index 69b66129fa..cd92547268 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -54,6 +54,7 @@
<p>All operations have an amortized O(1) running time, except
<seemfa marker="#filter/2"><c>filter/2</c></seemfa>,
+ <seemfa marker="#fold/3"><c>fold/3</c></seemfa>,
<seemfa marker="#join/2"><c>join/2</c></seemfa>,
<seemfa marker="#len/1"><c>len/1</c></seemfa>,
<seemfa marker="#member/2"><c>member/2</c></seemfa>,
@@ -134,6 +135,27 @@
</desc>
</func>
+ <func>
+ <name name="fold" arity="3" since=""/>
+ <fsummary>Fold a function over a queue.</fsummary>
+ <desc>
+ <p>Calls <c><anno>Fun</anno>(<anno>Item</anno>, <anno>AccIn</anno>)</c>
+ on successive items <c>Item</c> of <c>Queue</c>, starting
+ with <c><anno>AccIn</anno> == <anno>Acc0</anno></c>. The queue is
+ traversed in queue order, that is, from front to rear.
+ <c><anno>Fun</anno>/2</c> must return a new accumulator, which is
+ passed to the next call. The function returns the final value of
+ the accumulator. <c><anno>Acc0</anno></c> is returned if the queue is
+ empty.</p>
+ <p><em>Example:</em></p>
+ <pre>
+> <input>queue:fold(fun(X, Sum) -> X + Sum end, 0, queue:from_list([1,2,3,4,5])).</input>
+15
+> <input>queue:fold(fun(X, Prod) -> X * Prod end, 1, queue:from_list([1,2,3,4,5])).</input>
+120</pre>
+ </desc>
+ </func>
+
<func>
<name name="from_list" arity="1" since=""/>
<fsummary>Convert a list to a queue.</fsummary>
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 69ecfed94b..9a132f0330 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -27,7 +27,7 @@
-export([get/1,get_r/1,peek/1,peek_r/1,drop/1,drop_r/1]).
%% Higher level API
--export([reverse/1,join/2,split/2,filter/2]).
+-export([reverse/1,join/2,split/2,filter/2,fold/3]).
%% Okasaki API from klacke
-export([cons/2,head/1,tail/1,
@@ -402,6 +402,21 @@ filter_r(Fun, [X|R0]) ->
lists:reverse(L, R)
end.
+%% Fold a function over a queue, in queue order.
+%%
+%% O(len(Q))
+-spec fold(Fun, Acc0, Q :: queue(Item)) -> Acc1 when
+ Fun :: fun((Item, AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term().
+fold(Fun, Acc0, {R, F}) when is_function(Fun, 2), is_list(R), is_list(F) ->
+ Acc1 = lists:foldl(Fun, Acc0, F),
+ lists:foldr(Fun, Acc1, R);
+fold(Fun, Acc0, Q) ->
+ erlang:error(badarg, [Fun, Acc0, Q]).
+
%%--------------------------------------------------------------------------
%% Okasaki API inspired by an Erlang user contribution "deque.erl"
%% by Claes Wikstrom <klacke@kaja.klacke.net> 1999.
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index 569953dd9f..c85dd14278 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -373,6 +373,13 @@ do_op_test(F) ->
(_) -> [] end, MyQ4)),
[33,44] = queue:to_list(queue:filter(fun(X) when X < 27 -> false;
(X) -> [X] end, MyQ4)),
+ FoldQ = queue:from_list(L1),
+ FoldExp1 = lists:sum(L1),
+ FoldAct1 = queue:fold(fun(X,A) -> X+A end, 0, FoldQ),
+ FoldExp1 = FoldAct1,
+ FoldExp2 = [X*X || X <- L1],
+ FoldAct2 = queue:fold(fun(X,A) -> [X*X|A] end, [], FoldQ),
+ FoldExp2 = lists:reverse(FoldAct2),
%%
ok.
--
2.26.2