[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