[m-rev.] diff: add function versions of some predicates

Julien Fischer jfischer at opturion.com
Sun Mar 15 02:08:07 AEDT 2020


Add function versions of some predicates.

library/kv_list.m:
library/assoc_list.m:
     Add function versions of foldl_keys and foldl_values.

     Rename some variables for consistency.

NEWS:
     Announce the additions to the assoc_list module.

Julien.

diff --git a/NEWS b/NEWS
index 53ac30c..5661f39 100644
--- a/NEWS
+++ b/NEWS
@@ -61,13 +61,15 @@ Changes to the Mercury standard library

  ### Changes to the `assoc_list` module

-* The following predicates have been added:
+* The following predicates and functions have been added:

      - pred `lookup/3`
      - pred `update/4`
      - pred `foldl/4`
      - pred `foldl2/6`
      - pred `foldl3/8`
+    - func `foldl_keys/3`
+    - func `foldl_values/3`

  ### Changes to the `char` module

diff --git a/library/assoc_list.m b/library/assoc_list.m
index 0788739..a7173e9 100644
--- a/library/assoc_list.m
+++ b/library/assoc_list.m
@@ -2,7 +2,7 @@
  % vim: ft=mercury ts=4 sw=4 et
  %---------------------------------------------------------------------------%
  % Copyright (C) 1995-1997, 1999-2001, 2004-2006, 2010-2011 The University of Melbourne.
-% Copyright (C) 2013-2018 The Mercury team.
+% Copyright (C) 2013-2020 The Mercury team.
  % This file is distributed under the terms specified in COPYING.LIB.
  %---------------------------------------------------------------------------%
  %
@@ -203,6 +203,12 @@
  :- mode foldl(pred(in, in, di, uo) is semidet, in, di, uo) is semidet.
  :- mode foldl(pred(in, in, in, out) is nondet, in, in, out) is nondet.

+    % foldl_keys(Func List, Start) = End calls Func
+    % with each key in List, working left-to-right, and an accumulator
+    % whose initial value is Start, and returns the final value in End.
+    %
+:- func foldl_keys(func(K, A) = A, assoc_list(K, V), A) = A.
+
      % foldl_keys(Pred, List, Start End) calls Pred
      % with each key in List, working left-to-right, and an accumulator
      % whose initial value is Start, and returns the final value in End.
@@ -217,6 +223,12 @@
  :- mode foldl_keys(pred(in, in, out) is multi, in, in, out) is multi.
  :- mode foldl_keys(pred(in, in, out) is nondet, in, in, out) is nondet.

+    % foldl_values(Func List, Start) = End calls Func
+    % with each value in List, working left-to-right, and an accumulator
+    % whose initial value is Start, and returns the final value in End.
+    %
+:- func foldl_values(func(V, A) = A, assoc_list(K, V), A) = A.
+
      % foldl_values(Pred, List, Start End) calls Pred
      % with each value in List, working left-to-right, and an accumulator
      % whose initial value is Start, and returns the final value in End.
@@ -534,12 +546,24 @@ foldl(P, [K - V | KVs], !A) :-
      P(K, V, !A),
      foldl(P, KVs, !A).

+foldl_keys(_F, [], A) = A.
+foldl_keys(F, [KV | KVs], !.A) = !:A :-
+    KV = K - _V,
+    !:A = F(K, !.A),
+    !:A = assoc_list.foldl_keys(F, KVs, !.A).
+
  foldl_keys(_P, [], !A).
  foldl_keys(P, [KV | KVs], !A) :-
      KV = K - _V,
      P(K, !A),
      assoc_list.foldl_keys(P, KVs, !A).

+foldl_values(_F, [], A) = A.
+foldl_values(F, [KV | KVs], !.A) = !:A :-
+    KV = _K - V,
+    !:A = F(V, !.A),
+    !:A = assoc_list.foldl_values(F, KVs, !.A).
+
  foldl_values(_P, [], !A).
  foldl_values(P, [KV | KVs], !A) :-
      KV = _K - V,
diff --git a/library/kv_list.m b/library/kv_list.m
index 10b52ff..2b1527a 100644
--- a/library/kv_list.m
+++ b/library/kv_list.m
@@ -226,6 +226,12 @@
  :- mode foldl(pred(in, in, di, uo) is semidet, in, di, uo) is semidet.
  :- mode foldl(pred(in, in, in, out) is nondet, in, in, out) is nondet.

+    % foldl_keys(Func List, Start) = End calls Func
+    % with each key in List, working left-to-right, and an accumulator
+    % whose initial value is Start, and returns the final value in End.
+    %
+:- func foldl_keys(func(K, A) = A, kv_list(K, V), A) = A.
+
      % foldl_keys(Pred, List, Start End) calls Pred
      % with each key in List, working left-to-right, and an accumulator
      % whose initial value is Start, and returns the final value in End.
@@ -240,6 +246,12 @@
  :- mode foldl_keys(pred(in, in, out) is multi, in, in, out) is multi.
  :- mode foldl_keys(pred(in, in, out) is nondet, in, in, out) is nondet.

+    % foldl_values(Func List, Start) = End calls Func
+    % with each value in List, working left-to-right, and an accumulator
+    % whose initial value is Start, and returns the final value in End.
+    %
+:- func foldl_values(func(V, A) = A, kv_list(K, V), A) = A.
+
      % foldl_values(Pred, List, Start End) calls Pred
      % with each value in List, working left-to-right, and an accumulator
      % whose initial value is Start, and returns the final value in End.
@@ -565,21 +577,31 @@ merge(A @ kv_cons(AK, AV, AKVs), B @ kv_cons(BK, BV, BKVs), C) :-

  %---------------------------------------------------------------------------%

-foldl(_F, kv_nil, A) = A.
-foldl(F, kv_cons(K, V, TailKVs), !.A) = !:A :-
-    !:A = F(K, V, !.A),
-    !:A = foldl(F, TailKVs, !.A).
+foldl(_F, kv_nil, Acc) = Acc.
+foldl(F, kv_cons(K, V, TailKVs), !.Acc) = !:Acc :-
+    !:Acc = F(K, V, !.Acc),
+    !:Acc = foldl(F, TailKVs, !.Acc).

-foldl(_P, kv_nil, !A).
-foldl(P, kv_cons(K, V, TailKVs), !A) :-
-    P(K, V, !A),
-    foldl(P, TailKVs, !A).
+foldl(_P, kv_nil, !Acc).
+foldl(P, kv_cons(K, V, TailKVs), !Acc) :-
+    P(K, V, !Acc),
+    foldl(P, TailKVs, !Acc).
+
+foldl_keys(_F, kv_nil, Acc) = Acc.
+foldl_keys(F, kv_cons(K, _V, KVs), !.Acc) = !:Acc :-
+    !:Acc = F(K, !.Acc),
+    !:Acc = kv_list.foldl_keys(F, KVs, !.Acc).

  foldl_keys(_P, kv_nil, !Acc).
  foldl_keys(P, kv_cons(K, _V, KVs), !Acc) :-
      P(K, !Acc),
      kv_list.foldl_keys(P, KVs, !Acc).

+foldl_values(_F, kv_nil, Acc) = Acc.
+foldl_values(F, kv_cons(_K, V, KVs), !.Acc) = !:Acc :-
+    !:Acc = F(V, !.Acc),
+    !:Acc = kv_list.foldl_values(F, KVs, !.Acc).
+
  foldl_values(_P, kv_nil, !Acc).
  foldl_values(P, kv_cons(_K, V, KVs), !Acc) :-
      P(V, !Acc),


More information about the reviews mailing list