[mercury-users] Idea for a currying library
Richard A. O'Keefe
ok at hermes.otago.ac.nz
Tue Jan 11 13:12:56 AEDT 2000
On 07-Jan-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> Richard O'Keefe, I think, made the suggestion
> that some extra syntax be introduced, e.g.
>
> P = foo(X, #2, Y, #1)
>
> would translate into
>
> P = (func(A, B) = foo(X, B, Y, A))
>
> or somesuch.
My memory is like a sieve with holes in it, but I'm pretty sure someone
else suggested that, and I attacked it. I've had a strong dislike for
notations that require people to count, which is why I never really took
to Backus's FP, and why I'm sure I never suggested this, except perhaps as
a straw man.
> If adding more syntax is undesirable/too much
> trouble for now, it occurs to me that we could
> get some way towards solving the problem with
> a suitable library. The idea would be to
> provide currying functions for all the non-
> standard argument permutations for all functions
> up to a given arity, say 5. This library would
> look something like the following:
On the other hand, I've been using something very like this for years,
and could well have recommended *this* as a good enough notation.
Although I must say that I quickly abandoned it in Haskell and Clean;
"sections" are great for easy problems, but for hard ones, lambda-
notation is so much easier to get right. I include a copy of my Prolog
module; the comment was revised for this mailing.
% Module : callperm
% Author : Richard A. O'Keefe
% Updated: 2000.01
% Defines: Permutative calls.
:- module(callperm, [
% call/1,
call_1/2,
call_1_2/3,
call_2_1/3,
call_1_2_3/4,
call_1_3_2/4,
call_2_1_3/4,
call_2_3_1/4,
call_3_1_2/4,
call_3_2_1/4,
call_1_2_3_4/5,
call_1_3_2_4/5,
call_2_1_3_4/5,
call_2_3_1_4/5,
call_3_1_2_4/5,
call_3_2_1_4/5,
call_1_2_4_3/5,
call_1_3_4_2/5,
call_2_1_4_3/5,
call_2_3_4_1/5,
call_3_1_4_2/5,
call_3_2_4_1/5,
call_1_4_2_3/5,
call_1_4_3_2/5,
call_2_4_1_3/5,
call_2_4_3_1/5,
call_3_4_1_2/5,
call_3_4_2_1/5,
call_4_1_2_3/5,
call_4_1_3_2/5,
call_4_2_1_3/5,
call_4_2_3_1/5,
call_4_3_1_2/5,
call_4_3_2_1/5
]).
:- use_module(library(call), [
call/2,
call/3,
call/4,
call/5
]).
:- meta_predicate
% call(0),
call_1(1, ?),
call_1_2(2, ?, ?),
call_2_1(2, ?, ?),
call_1_2_3(3, ?, ?, ?),
call_1_3_2(3, ?, ?, ?),
call_2_1_3(3, ?, ?, ?),
call_2_3_1(3, ?, ?, ?),
call_3_1_2(3, ?, ?, ?),
call_3_2_1(3, ?, ?, ?),
call_1_2_3_4(4, ?, ?, ?, ?),
call_1_3_2_4(4, ?, ?, ?, ?),
call_2_1_3_4(4, ?, ?, ?, ?),
call_2_3_1_4(4, ?, ?, ?, ?),
call_3_1_2_4(4, ?, ?, ?, ?),
call_3_2_1_4(4, ?, ?, ?, ?),
call_1_2_4_3(4, ?, ?, ?, ?),
call_1_3_4_2(4, ?, ?, ?, ?),
call_2_1_4_3(4, ?, ?, ?, ?),
call_2_3_4_1(4, ?, ?, ?, ?),
call_3_1_4_2(4, ?, ?, ?, ?),
call_3_2_4_1(4, ?, ?, ?, ?),
call_1_4_2_3(4, ?, ?, ?, ?),
call_1_4_3_2(4, ?, ?, ?, ?),
call_2_4_1_3(4, ?, ?, ?, ?),
call_2_4_3_1(4, ?, ?, ?, ?),
call_3_4_1_2(4, ?, ?, ?, ?),
call_3_4_2_1(4, ?, ?, ?, ?),
call_4_1_2_3(4, ?, ?, ?, ?),
call_4_1_3_2(4, ?, ?, ?, ?),
call_4_2_1_3(4, ?, ?, ?, ?),
call_4_2_3_1(4, ?, ?, ?, ?),
call_4_3_1_2(4, ?, ?, ?, ?),
call_4_3_2_1(4, ?, ?, ?, ?).
/* The basic idea of these predicates is that
call_<pi[1]>..._<pi[n]>(p(X1,...,Xm), Y1,...,Yn) :-
p(X1, ..., Xm, Y<pi[1]>, ..., Y<pi[n]>).
where pi[] is a permutation of 1..n.
Oddly enough, they are not meant to be called directly. If you can
write call_2_1_3(P, Y, X, Z) directly, then you could have written
call(P, X, Y, Z) directly, and more clearly. The idea is that you
can use these things to build closures that can be passed around and
called using the call/N family, and decide the argument order at the
point where the closure is MADE (not called). To take a specific
example, if you want to check whether all the elements of a list are
strictly positive, the obvious thing is to write
maplist(>(0), Numbers)
It may be obvious, but it's wrong. You have to write <(0) instead,
which is counter-intuitive, and the converse relation isn't always
available. What you can do with the aid of this module is write
maplist(call_2_1(>,0), Numbers).
Let's see how that works. Let's say the first element of the list
is 137. Then maplist/2 will do
call(call_2_1(>,0), 137)
:- call_2_1(>, 0, 137)
:- call(>, 137, 0)
:- 137 > 0
which is what we want.
There are two reasons why this set of permutative calls stops at 4
additional arguments. The first is that we'd need 120 predicates to
handle 5 arguments. The second is that even with 4 arguments I have
to stop and draw a diagram to make sure I'm using these things
correctly; the notation (like all notations that require people to
count) simply doesn't scale well.
*/
/*
call(G) :- call(G).
*/
call_1(G, Y1) :- call(G, Y1).
call_1_2(G, Y1, Y2) :- call(G, Y1, Y2).
call_2_1(G, Y1, Y2) :- call(G, Y2, Y1).
call_1_2_3(G, Y1, Y2, Y3) :- call(G, Y1, Y2, Y3).
call_1_3_2(G, Y1, Y2, Y3) :- call(G, Y1, Y3, Y2).
call_2_1_3(G, Y1, Y2, Y3) :- call(G, Y2, Y1, Y3).
call_2_3_1(G, Y1, Y2, Y3) :- call(G, Y2, Y3, Y1).
call_3_1_2(G, Y1, Y2, Y3) :- call(G, Y3, Y1, Y2).
call_3_2_1(G, Y1, Y2, Y3) :- call(G, Y3, Y2, Y1).
call_1_2_3_4(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y2, Y3, Y4).
call_1_3_2_4(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y3, Y2, Y4).
call_2_1_3_4(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y1, Y3, Y4).
call_2_3_1_4(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y3, Y1, Y4).
call_3_1_2_4(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y1, Y2, Y4).
call_3_2_1_4(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y2, Y1, Y4).
call_1_2_4_3(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y2, Y4, Y3).
call_1_3_4_2(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y3, Y4, Y2).
call_2_1_4_3(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y1, Y4, Y3).
call_2_3_4_1(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y3, Y4, Y1).
call_3_1_4_2(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y1, Y4, Y2).
call_3_2_4_1(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y2, Y4, Y1).
call_1_4_2_3(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y4, Y2, Y3).
call_1_4_3_2(G, Y1, Y2, Y3, Y4) :- call(G, Y1, Y4, Y3, Y2).
call_2_4_1_3(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y4, Y1, Y3).
call_2_4_3_1(G, Y1, Y2, Y3, Y4) :- call(G, Y2, Y4, Y3, Y1).
call_3_4_1_2(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y4, Y1, Y2).
call_3_4_2_1(G, Y1, Y2, Y3, Y4) :- call(G, Y3, Y4, Y2, Y1).
call_4_1_2_3(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y1, Y2, Y3).
call_4_1_3_2(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y1, Y3, Y2).
call_4_2_1_3(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y2, Y1, Y3).
call_4_2_3_1(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y2, Y3, Y1).
call_4_3_1_2(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y3, Y1, Y2).
call_4_3_2_1(G, Y1, Y2, Y3, Y4) :- call(G, Y4, Y3, Y2, Y1).
end_of_file.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list