[m-rev.] diff: fix the modes of array.map

Julien Fischer jfischer at opturion.com
Thu Aug 16 16:15:44 AEST 2018


Fix the modes of array.map.

library/array.m:
     The current modes for array.map do not match what the implementation
     actually does: specifically, map does not destructively update its
     input array argument.

     Call unsafe_init/3 in a few spots where it is safe to do so.

tests/hard_coded/ho_array_ops.{m,exp}:
     Extend this test to cover array.map.

Julien.

diff --git a/library/array.m b/library/array.m
index fe07597..d4f5488 100644
--- a/library/array.m
+++ b/library/array.m
@@ -473,10 +473,12 @@
      % each of the elements of `OldArray' to create `NewArray'.
      %
  :- pred map(pred(T1, T2), array(T1), array(T2)).
-:- mode map(pred(in, out) is det, array_di, array_uo) is det.
+%:- mode map(pred(in, out) is det, array_ui, array_uo) is det.
+:- mode map(pred(in, out) is det, in, array_uo) is det.

  :- func map(func(T1) = T2, array(T1)) = array(T2).
-:- mode map(func(in) = out is det, array_di) = array_uo is det.
+%:- mode map(func(in) = out is det, array_ui) = array_uo is det.
+:- mode map(func(in) = out is det, in) = array_uo is det.

  :- func array_compare(array(T), array(T)) = comparison_result.
  :- mode array_compare(in, in) = uo is det.
@@ -2897,7 +2899,7 @@ map_foldl(P, A, B, !Acc) :-
      else
          array.unsafe_lookup(A, 0, X),
          P(X, Y, !Acc),
-        B1 = array.init(N, Y),
+        B1 = unsafe_init(N, Y, 0),
          map_foldl_2(P, 1, A, B1, B, !Acc)
      ).

@@ -2935,7 +2937,7 @@ map_corresponding_foldl(P, A, B, C, !Acc) :-
          array.unsafe_lookup(A, 0, X),
          array.unsafe_lookup(B, 0, Y),
          P(X, Y, Z, !Acc),
-        C1 = array.init(SizeA, Z),
+        C1 = unsafe_init(SizeA, Z, 0),
          map_corresponding_foldl_2(P, 1, SizeA, A, B, C1, C, !Acc)
      ).

diff --git a/tests/hard_coded/ho_array_ops.exp b/tests/hard_coded/ho_array_ops.exp
index 38b5b91..1c6744a 100644
--- a/tests/hard_coded/ho_array_ops.exp
+++ b/tests/hard_coded/ho_array_ops.exp
@@ -100,6 +100,36 @@ TESTING: foldl2_corresponding (mismatch)
  RESULT: EXCEPTION: software_error("predicate `array.foldl2_corresponding\'/7: Unexpected: mismatched array sizes")
  FINISHED TESTING: foldl2_corresponding (mismatch)

+TESTING: map (pred) (empty)
+array([])
+RESULT: OK
+FINISHED TESTING: map (pred) (empty)
+
+TESTING: map (pred) (singleton)
+array(["1"])
+RESULT: OK
+FINISHED TESTING: map (pred) (singleton)
+
+TESTING: map (pred) (> 1)
+array(["1", "2", "3"])
+RESULT: OK
+FINISHED TESTING: map (pred) (> 1)
+
+TESTING: map (func) (empty)
+array([])
+RESULT: OK
+FINISHED TESTING: map (func) (empty)
+
+TESTING: map (func) (singleton)
+array(["1"])
+RESULT: OK
+FINISHED TESTING: map (func) (singleton)
+
+TESTING: map (func) (> 1)
+array(["1", "2", "3"])
+RESULT: OK
+FINISHED TESTING: map (func) (> 1)
+
  TESTING: map_corresponding_foldl (ok)
  1 + 2 = 3
  2 + 4 = 6
diff --git a/tests/hard_coded/ho_array_ops.m b/tests/hard_coded/ho_array_ops.m
index b92ecb6..1ecac4c 100644
--- a/tests/hard_coded/ho_array_ops.m
+++ b/tests/hard_coded/ho_array_ops.m
@@ -53,6 +53,14 @@ main(!IO) :-
      do_test("foldl2_corresponding (mismatch)", foldl2_corresponding_mismatch,
          !IO),

+    do_test("map (pred) (empty)", map_pred_test([]), !IO),
+    do_test("map (pred) (singleton)", map_pred_test([1]), !IO),
+    do_test("map (pred) (> 1)", map_pred_test([1, 2, 3]), !IO),
+
+    do_test("map (func) (empty)", map_func_test([]), !IO),
+    do_test("map (func) (singleton)", map_func_test([1]), !IO),
+    do_test("map (func) (> 1)", map_func_test([1, 2, 3]), !IO),
+
      do_test("map_corresponding_foldl (ok)", map_corresponding_foldl_ok, !IO),
      do_test("map_corresponding_foldl (empty)", map_corresponding_foldl_empty,
          !IO),
@@ -200,6 +208,22 @@ print_and_sum_corresponding(A, B, !Sum, !IO) :-

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

+:- pred map_pred_test(list(int)::in, io::di, io::uo) is det.
+
+map_pred_test(Elems, !IO) :-
+    A = array.from_list(Elems),
+    array.map(int_to_string, A, B),
+    io.write_line(B, !IO).
+
+:- pred map_func_test(list(int)::in, io::di, io::uo) is det.
+
+map_func_test(Elems, !IO) :-
+    A  = array.from_list(Elems),
+    B : array(string) = array.map(int_to_string, A),
+    io.write_line(B, !IO).
+
+%---------------------------------------------------------------------------%
+
  :- pred map_corresponding_foldl_ok(io::di, io::uo) is det.

  map_corresponding_foldl_ok(!IO) :-


More information about the reviews mailing list