mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 01:43:35 +00:00
Improve documentation and test coverage for the same.
library/list.m:
Change the behaviour of take/3 and drop/3 so they fail if their
first argument is negative. This makes them consistent with
the behaviour of split_list/4 and is arguably less surprising than
their current behaviour.
Make split_list/4 more efficient by not doing two comparison
operations per recursive call.
Re-implement det_drop/3 in terms of drop/3.
Fix the documentation of the failure condition of split_list/4,
take/3 and drop/3; all three omitted the description of what
happens if their first argument is negative.
Use 'N' rather than 'Len' for the name of the first argument
in the comments describing the above predicates; the latter
is ambiguous.
NEWS:
Announce the change in behaviour of take/3 and drop/3.
tests/hard_coded/list_split_take_drop.{m,exp}:
Test the behaviour of the above predicates and also check that the
expected relationships between them hold.
tests/hard_coded/Mmakefile:
Add the new test.
127 lines
3.1 KiB
Mathematica
127 lines
3.1 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module list_split_take_drop.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
:- import_module pair.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
list.foldl(run_test, tests, !IO).
|
|
|
|
:- pred run_test(pair(int, list(int))::in, io::di, io::uo) is det.
|
|
|
|
run_test(N - List, !IO) :-
|
|
NStr = describe_int(N),
|
|
ListStr = string(List),
|
|
|
|
% Test split_list/4.
|
|
%
|
|
io.format("split_list(%s, %s) ===> ", [s(NStr), s(ListStr)], !IO),
|
|
( if list.split_list(N, List, SplitStart, SplitEnd) then
|
|
io.format("(%s, %s)\n", [s(string(SplitStart)), s(string(SplitEnd))], !IO),
|
|
MaybeSplitStart = yes(SplitStart),
|
|
MaybeSplitEnd = yes(SplitEnd)
|
|
else
|
|
write_false(!IO),
|
|
MaybeSplitStart = no,
|
|
MaybeSplitEnd = no
|
|
),
|
|
|
|
% Test drop/3.
|
|
%
|
|
io.format("drop(%s, %s) ===> ", [s(NStr), s(ListStr)], !IO),
|
|
( if list.drop(N, List, DropEnd) then
|
|
io.format("%s\n", [s(string(DropEnd))], !IO),
|
|
MaybeDropEnd = yes(DropEnd)
|
|
else
|
|
write_false(!IO),
|
|
MaybeDropEnd = no
|
|
),
|
|
|
|
% Test take/3.
|
|
%
|
|
io.format("take(%s, %s) ===> ", [s(NStr), s(ListStr)], !IO),
|
|
( if list.take(N, List, TakeStart) then
|
|
io.format("%s\n", [s(string(TakeStart))], !IO),
|
|
MaybeTakeStart = yes(TakeStart)
|
|
else
|
|
write_false(!IO),
|
|
MaybeTakeStart = no
|
|
),
|
|
|
|
% Check that drop(N, List, End) <=> split_list(N, List, _, End).
|
|
%
|
|
( if MaybeSplitEnd = MaybeDropEnd then
|
|
true
|
|
else
|
|
io.format("ERROR: split_list/4 and drop/3 differ for (%s, %s)\n",
|
|
[s(NStr), s(ListStr)], !IO)
|
|
),
|
|
|
|
% Check that take(N, List, Start) <=> split_list(N, List, Start, _)
|
|
%
|
|
( if MaybeSplitStart = MaybeTakeStart then
|
|
true
|
|
else
|
|
io.format("ERROR: split_list/4 and take/3 differ for (%s, %s)\n",
|
|
[s(NStr), s(ListStr)], !IO)
|
|
),
|
|
io.nl(!IO).
|
|
|
|
:- func tests = assoc_list(int, list(int)).
|
|
|
|
tests = [
|
|
int.min_int - [],
|
|
int.min_int - [111],
|
|
int.min_int - [111, 222],
|
|
-1 - [],
|
|
-1 - [111],
|
|
-1 - [111, 222],
|
|
0 - [],
|
|
0 - [111],
|
|
0 - [111, 222],
|
|
1 - [],
|
|
1 - [111],
|
|
1 - [111, 222],
|
|
2 - [],
|
|
2 - [111],
|
|
2 - [111, 222],
|
|
2 - [111, 222, 333],
|
|
int.max_int - [],
|
|
int.max_int - [111],
|
|
int.max_int - [111, 222]
|
|
].
|
|
|
|
:- func describe_int(int) = string.
|
|
|
|
describe_int(N) =
|
|
( if N = int.min_int then
|
|
"int.min_int"
|
|
else if N = int.max_int then
|
|
"int.max_int"
|
|
else
|
|
int_to_string(N)
|
|
).
|
|
|
|
:- pred write_false(io::di, io::uo) is det.
|
|
|
|
write_false(!IO) :-
|
|
io.write_string("<<FALSE>>\n", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module list_split_take_drop.
|
|
%---------------------------------------------------------------------------%
|