[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