currying higher-order predicates
fjh at cs.mu.oz.au
Tue Apr 22 12:04:42 AEST 1997
Bart Demoen, you wrote:
> Maybe I can get help from you with some other problem: the following
> is a bit clumsily declared I suppose, but the idea is: I have a
> closure which works on 2 arguments; I want to construct a closure that
> works on one argument by providing the first argument; how can I do
> that - in the code below, when I use call instead of apply, the
> compiler tells me to use apply;
Ah, not quite. It tells you "if you are trying to call a higher-order
function, you should use apply". But you're not doing that, you're
trying to curry (not call) a higher-order predicate (not function).
> when using apply, it tells me the types are wrong
> :- pred b(pred(list(int),int),pred(int)).
> :- mode b(((pred(in,out) is det) -> (pred(in,out) is det)),
> (free -> (pred(out) is det))) is det.
> b(X,Y) :- Y = apply(X,[4,5,6]).
In Mercury call/N cannot be curried.
You can only curry predicates (or functions), and call/N is
a builtin language construct, not a predicate.
(The main reason for this is that allowing currying of call/N would
make type checking more difficult.)
There are several simple solutions:
% in Mercury >= 0.7
b(X,Y) :- Y = (pred(Z::out) is det :- X([4,5,6],Z).
% in Mercury >= 0.5
b(X,Y) :- Y = lambda([Z::out] is det, call(X, [4,5,6], Z)).
% in Mercury >= 0.5
b(X,Y) :- Y = my_call(X, [4,5,6]).
:- pred my_call(pred(T1, T2), T1, T2). % pred decl optional
:- mode my_call(pred(in, out) is det, in, out) is det.
my_call(X, Y, Z) :- call(X, Y, Z).
This is not documented very well. I'll add some documentation to
the Mercury language reference manual, and add a pointer to that
documentation to the compiler error message. Thanks for the suggestion.
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 188.8.131.52 | -- the last words of T. S. Garp.
More information about the users