[m-rev.] for review: add predicate versions of int.fold_up/down

Ralph Becket rafe at cs.mu.OZ.AU
Sat Mar 27 09:19:46 AEDT 2004


Julien Fischer, Friday, 26 March 2004:
> 
> Estimated hours taken: 1
> Branches: main
> 
> Add predicate versions of int.fold_up and int.fold_down.
> 
> XXX We should probably consider swapping the order of
> the arguments in the function versions so they correspond
> to the predicate versions more closely.
> 
> library/int.m:
> 	Add the predicates int.fold_up/5 and int.fold_down/5.

While you're at it, could you also add int.fold_up2/7 and
int.fold_down2/7 (the fold2 variants are useful enough to warrant
inclusion in the library):

:- pred fold_up2(pred(int, T1, T1, T2, T2), int, int, T1, T1, T2, T2)
		is det.
:- mode fold_up2(pred(in, in, out, in, out) is det, in, in, out, in, out)
		is det.
:- mode fold_up2(pred(in, in, out, di, uo) is det, in, in, out, di, uo)
		is det.

fold_up2(P, Lo, Hi, !A, !B) :-
	( if   Lo =< Hi
	  then P(Lo, !A, !B), fold_up2(P, Lo + 1, Hi, !A, !B)
	  else true
	).

:- pred fold_down2(pred(int, T1, T1, T2, T2), int, int, T1, T1, T2, T2)
		is det.
:- mode fold_down2(pred(in, in, out, in, out) is det, in, in, out, in, out)
		is det.
:- mode fold_down2(pred(in, in, out, di, uo) is det, in, in, out, di, uo)
		is det.

fold_down2(P, Lo, Hi, !A, !B) :-
	( if   Lo =< Hi
	  then P(Lo, !A, !B), fold_down2(P, Lo, Hi - 1, !A, !B)
	  else true
	).

> tests/hard_coded/int_fold_up_down.m:
> tests/hard_coded/int_fold_up_down.exp:
> 	Test the predicate versions as well.
> 
> NEWS:
> 	Mention the new predicates.
> 
> Julien.
> 
> Index: NEWS
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/NEWS,v
> retrieving revision 1.330
> diff -u -r1.330 NEWS
> --- NEWS	19 Mar 2004 14:33:36 -0000	1.330
> +++ NEWS	26 Mar 2004 06:05:35 -0000
> @@ -91,8 +91,9 @@
> 
>  Changes to the Mercury standard library:
> 
> -* We've added two new functions, fold_up/4 and fold_down/4, to int.m.
> -  These functions support iteration over contiguous integer ranges.
> +* We've add some new predicates and functions to int.m.
> +  int.fold_up/4, int.fold_down/4, int.fold_up/5, int.fold_down/5
> +  support iteration over contiguous integer ranges.
> 
>  * We've added a new library module, `array2d', for two-dimensional arrays.
> 
> Index: library/int.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/int.m,v
> retrieving revision 1.98
> diff -u -r1.98 int.m
> --- library/int.m	2 Feb 2004 03:53:07 -0000	1.98
> +++ library/int.m	26 Mar 2004 00:34:35 -0000
> @@ -233,15 +233,31 @@
>  :- func int__bits_per_int = int.
>  :- pred int__bits_per_int(int::out) is det.
> 
> +	% fold_up(F, Low, High, !Acc) <=> list.foldl(F, Low `..` High, !Acc)
> +	%
> +	% NOTE: fold_up/5 is undefined if High = int.max_int.
> +	%
> +:- pred int__fold_up(pred(int, T, T), int, int, T, T).
> +:- mode int__fold_up(pred(in, in, out) is det, in, in, in, out) is det.
> +:- mode int__fold_up(pred(in, di, uo) is det, in, in, di, uo) is det.

The list.fold[lr] predicates have more comprehensive mode coverage:

:- pred list__foldl(pred(X, Y, Y), list(X), Y, Y).
:- mode list__foldl(pred(in, di, uo) is det, in, di, uo) is det.
:- mode list__foldl(pred(in, in, out) is det, in, in, out) is det.
:- mode list__foldl(pred(in, in, out) is semidet, in, in, out) is semidet.
:- mode list__foldl(pred(in, in, out) is nondet, in, in, out) is nondet.
:- mode list__foldl(pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
:- mode list__foldl(pred(in, in, out) is cc_multi, in, in, out) is cc_multi.

It's probably a good idea to do the same thing here.

> +
>  	% fold_up(F, Acc, Low, High) = list.foldl(F, Low `..` High, Acc)
>  	%
> -	% NOTE: fold_up/4 is undefined if High = int__max_int.
> +	% NOTE: fold_up/4 is undefined if High = int.max_int.
>  	%
>  :- func int__fold_up(func(int, T) = T, T, int, int) = T.
> 
> +	% fold_down(F, Low, High, !Acc) <=> list.foldr(F, Low `..` High, !Acc)
> +	%
> +	% NOTE: fold_down/5 is undefined if Low int.min_int.
> +	%
> +:- pred int__fold_down(pred(int, T, T), int, int, T, T).
> +:- mode int__fold_down(pred(in, in, out) is det, in, in, in, out) is det.
> +:- mode int__fold_down(pred(in, di, uo) is det, in, in, di, uo) is det.

Ditto.

> +
>  	% fold_down(F, Acc, Low, High) = list.foldr(F, Low `..` High, Acc)
>  	%
> -	% NOTE: fold_down/4 is undefined if Low = int__min_int.
> +	% NOTE: fold_down/4 is undefined if Low = int.min_int.
>  	%
>  :- func int__fold_down(func(int, T) = T, T, int, int) = T.
> 
> @@ -674,10 +690,22 @@
> 
>  %-----------------------------------------------------------------------------%
> 
> +int__fold_up(F, Lo, Hi, !A) :-
> +	( if	Lo =< Hi
> +	  then	F(Lo, !A), int__fold_up(F, Lo + 1, Hi, !A)
> +	  else	true
> +	).
> +

I would have used `P' rather than `F' for the closure name.

>  int__fold_up(F, A, Lo, Hi) =
>  	( if Lo =< Hi then int__fold_up(F, F(Lo, A), Lo + 1, Hi) else A ).
> 
>  %-----------------------------------------------------------------------------%
> +
> +int__fold_down(F, Lo, Hi, !A) :-
> +	( if 	Lo =< Hi
> +	  then	F(Hi, !A), int__fold_down(F, Lo, Hi - 1, !A)
> +	  else	true
> +	).

Ditto.

Otherwise that looks fine.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list