[mercury-users] Passing a multi-mode higher order predicate
Julian Fondren
ayrnieu at gmail.com
Sun Feb 5 18:46:39 AEDT 2012
On Sat, Feb 4, 2012 at 11:51 PM, Jeff Thompson <jeff at thefirst.org> wrote:
> Hello again. In the program below, the compiler gives the following error
> due to "test(list.member)".
>
> test.m:010: In clause for `main(di, uo)':
> test.m:010: in argument 1 of call to predicate `test.test'/1:
> test.m:010: mode error: variable `V_6' has instantiatedness `free',
> test.m:010: expected instantiatedness was `(pred((ground >> ground),
> (ground
> test.m:010: >> ground)) is semidet)'.
>
> The predicate list.member exists with the correct mode, so why does the
> compiler say the argument is free?
>
> :- module test.
> :- interface.
> :- import_module io.
> :- pred main(io__state::di, io__state::uo) is cc_multi.
io__state = io.state = io.io; and as you used 'import_module' rather
than 'use_module', io.io = io. So,
:- pred main(io::di, io::uo) is cc_multi.
> :- implementation.
> :- import_module int, list.
>
> main(!IO) :-
> if test(list.member) then io.write_string("yes", !IO) else
> io.write_string("no", !IO).
> :- pred test(pred(int, list(int))).
> :- mode test(pred(in, in) is semidet) is semidet.
OK, given test(X), we know that X is a semidet predicate that accepts an
int and a list of ints. But, er, what is the mode of X? i.e., does
test produce X? Is X bound to such a predicate by test(X)? Or does it
accept an X, perhaps failing when you give it the wrong X? Your :- mode
line should answer this basic question, but it doesn't. (Or rather, it
answers it in a very odd way, which you can see in your error
message.)
>From section 8.3 of the Mercury Language Reference, Higher-order modes:
If you want to define a predicate which returns a higher-order
predicate term, you would use a mode such as `free >> pred(...) is
...', or `out(pred(...) is ... )'. For example:
erm, I'll give my own example:
:- pred foo(pred(int)).
:- mode foo(free >> (pred(out) is multi)) is det.
foo(numbers).
:- pred numbers(int::out) is det.
numbers(1).
numbers(2).
numbers(3).
That could be written:
:- type producer(T) == pred(T).
:- inst producer == (pred(out) is multi).
:- pred foo(producer::out(producer)) is det.
foo(numbers).
Cheers,
Julian
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to: mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions: mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the users
mailing list