[m-rev.] for review: Add det_take to the list module
Paul Bone
paul at bone.id.au
Sat Dec 21 17:25:38 AEDT 2013
Branches: master
For review by anyone
Add det_take to the list module
The list module currently contains take, drop and det_drop predicates, but
no det_take predicate. Developers could use det_split_list instead, however
det_take is more straight-forward and can be expected to exist since
det_drop exists.
library/list.m:
As above.
NEWS:
Announce the new predicate.
---
NEWS | 4 ++--
library/list.m | 28 +++++++++++++++++++++-------
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/NEWS b/NEWS
index e77be99..bd32a96 100644
--- a/NEWS
+++ b/NEWS
@@ -18,8 +18,8 @@ Changes to the Mercury standard library:
* We have added the following predicates and functions to the map module:
det_min_key/1, det_max_key/1, foldl2_values/6 and foldl3_values/8.
-* We have added the following predicates to the list module: foldr2/6 and
- foldr3/8.
+* We have added the following predicates to the list module: foldr2/6,
+ foldr3/8 and det_take/3.
* We have added the following predicates to the bag module: foldl/4 and
foldl2/6.
diff --git a/library/list.m b/library/list.m
index d3f1856..8298ece 100644
--- a/library/list.m
+++ b/library/list.m
@@ -232,12 +232,19 @@
:- pred list.split_upto(int::in, list(T)::in, list(T)::out, list(T)::out)
is det.
- % list.take(Len, List, Start):
+ % take(Len, List, Start):
%
% `Start' is the first `Len' elements of `List'. Fails if `List' has
% less than `Len' elements. See also: list.split_list.
%
-:- pred list.take(int::in, list(T)::in, list(T)::out) is semidet.
+:- pred take(int::in, list(T)::in, list(T)::out) is semidet.
+
+ % det_take(Len, List, Start):
+ %
+ % As above. Rather than failing when there are fewer than Len items in
+ % List det_take will throw an exception.
+ %
+:- pred det_take(int::in, list(T)::in, list(T)::out) is det.
% list.take_upto(Len, List, Start):
%
@@ -2231,13 +2238,20 @@ list.split_upto(N, List, Start, End) :-
End = List
).
-list.take(N, As, Bs) :-
+take(N, Xs0, Xs) :-
( N > 0 ->
- As = [A | As1],
- list.take(N - 1, As1, Bs1),
- Bs = [A | Bs1]
+ Xs0 = [X | Xs1],
+ take(N - 1, Xs1, Xs2),
+ Xs = [X | Xs2]
+ ;
+ Xs = []
+ ).
+
+det_take(N, As, Bs) :-
+ ( take(N, As, BsPrime) ->
+ Bs = BsPrime
;
- Bs = []
+ unexpected($file, $pred, "Unexpected end of list")
).
list.take_upto(N, Xs) = Ys :-
--
1.8.5.1
More information about the reviews
mailing list